Неопределенные символы при связывании OSMalloc.h с использованием clang в OS X

Здравствуйте и спасибо за вашу помощь.

Я пытаюсь создать простой "привет мир", используя только низкоуровневые вызовы ядра OS X для выделения памяти и записи в stdout. Зачем? Я заканчиваю главу 8 второго издания K&R, которая посвящена написанию стандартной файловой библиотеки с нуля. Это, конечно, полностью устарело, но концепция главы остается. Во всяком случае, я не могу понять, как правильно связать, чтобы все заработало, и, таким образом, зарабатываю на себе множество приятных неопределенных ошибок символов.

Я проанализировал много других вопросов, вызывающих ту же ошибку, но не нашел ни одного, который бы касался ссылки в библиотеке ядра, которую я пытаюсь использовать. Сумасшедший длинный путь в третьем #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;
}

Makefile:

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, если вам нужен низкоуровневый режим? Это будет соответствовать вашему использованию записи и не должно вызывать проблем со связыванием". (из CRD)

Использование "sbrk" (и его двоюродного брата "brk") было первоначальным путем, по которому я шел; однако на странице руководства для sbrk говорится: "Функции brk и sbrk - это исторические курьезы, оставшиеся с более ранних дней до появления управления виртуальной памятью". Это утверждение направило меня на путь поиска его замены."malloc" - это, конечно, правильная и нормальная утилита для выделения памяти. Однако глава 8 K&R посвящена написанию ваших собственных системных вызовов базовой ОС. Итак, базовый вызов, который я смог найти для OS X Darwin, это "OSMalloc", который я пытаюсь использовать.

1 ответ

OSMalloc доступен только для написания самого ядра (расширения ядра, драйверы устройств). Пользовательские программы должны использовать sbrk.

Другие вопросы по тегам