在OS X上使用clang链接OSMalloc.h时未定义的符号

时间:2016-08-13 21:56:29

标签: c macos kernel clang kernighan-and-ritchie

您好,感谢您的协助。

我正在尝试使用低级OS X内核调用来创建一个简单的“hello world”来分配内存并写出到stdout。为什么?我正在完成第二版K& R的第8章,它专注于从头开始编写标准文件库。当然,这完全是过时的,但本章的概念仍然存在。无论如何,我似乎无法弄清楚如何正确链接以使所有事情都能解决,从而为自己赚取了许多不错的未定义符号错误。

我已经解决了导致相同错误的许多其他问题,但是没有找到任何解决如何在我尝试使用的内核库中进行链接的问题。第三个#include中的疯狂长路径需要在链接错误之前才能编译。

守则:

#include <fcntl.h>
#include <unistd.h> // equivalent to (K&R) #include "syscalls.h"
#include </Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.11.sdk/System/Library/Frameworks/Kernel.framework/Versions/A/Headers/libkern/OSMalloc.h> // for low-level memory allocation

#define MINSTDIOTAG "com.apple.minstdio" // Used by OSMalloc from <libkern/OSMalloc.h>
#define PAGE_SIZE_64K (64 * 1024)        // Page size to allocate

int main(void) {

    char *base    = NULL; // Memory buffer
    char *ptr     = base; // Location in buffer

    // Create tag
    OSMallocTag mytag = OSMalloc_Tagalloc(MINSTDIOTAG, OSMT_DEFAULT);

    // Attempt to allocate PAGE_SIZE_64K of memory
    if ((base = (char *)OSMalloc(PAGE_SIZE_64K, mytag)) == NULL)
        return 1;
    ptr = base;

    // Stuff the buffer with stuff
    *ptr++ = 'f';
    *ptr++ = 'o';
    *ptr++ = 'o';
    *ptr++ = '\n';
    *ptr   = '\0';

    // Write it out to stdout
    (void)write(STDOUT_FILENO, base, (size_t)(ptr - base));

    // Free allocated memory
    OSFree(base, PAGE_SIZE_64K, mytag);

    // Get out of Dodge City, Kansas
    return 0;
}

生成文件:

BIN = ../../bin
ODIR = obj
CC = cc
CFLAGS = -std=c99 -Wall -g -I.
_OBJ = minstdio3.o
_BIN = minstdio3
OBJ = $(patsubst %,$(ODIR)/%,$(_OBJ))

.PHONY: all clean

all: $(_BIN)

clean:
    rm -rv $(ODIR) $(_BIN)

minstdio3: $(ODIR)/minstdio3.o
    $(CC) $(CFLAGS) $^ -o $@
    cp -v $@ $(BIN)/$@

$(ODIR)/%.o: %.c $(DEPS)
    mkdir -pv $(ODIR)
    $(CC) $(CFLAGS) -c -o $@ $<

收到的错误:

Todds-MBP-2:cbasics todddecker$ make
mkdir -pv obj
cc -std=c99 -Wall -g -I. -c -o obj/minstdio3.o minstdio3.c
cc -std=c99 -Wall -g -I. obj/minstdio3.o -o minstdio3
Undefined symbols for architecture x86_64:
  "_OSFree", referenced from:
      _main in minstdio3.o
  "_OSMalloc", referenced from:
      _main in minstdio3.o
  "_OSMalloc_Tagalloc", referenced from:
      _main in minstdio3.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make[2]: *** [minstdio3] Error 1

- 编辑 -

“如果你想要低级别,你为什么不使用sbrk系统调用?这与你使用写入相匹配,不应该给出任何链接问题。”(来自{{3} })

  

使用'sbrk'(它是堂兄'brk')是我走向的原始路径;然而,'sbrk'的手册页指出,“brk和sbrk功能是虚拟内存管理出现前几天遗留下来的历史好奇心。”这句话让我走上了试图发现其替代品的道路。当然,'malloc'是内存分配的正确和正常的实用程序。然而,K&amp; R第8章是关于从基本OS系统调用编写自己的。因此,我能够为OS X Darwin找到的基本调用是'OSMalloc',我正在尝试使用它。

1 个答案:

答案 0 :(得分:0)

OSMalloc仅可用于编写内核本身(内核扩展,设备驱动程序)。用户程序必须使用sbrk。