Неопределенные символы при связывании 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.