2016-08-13 10 views
0

Здравствуйте и благодарю вас за помощь.Неопределенные символы при связывании 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 [email protected] 
    cp -v [email protected] $(BIN)/[email protected] 

$(ODIR)/%.o: %.c $(DEPS) 
    mkdir -pv $(ODIR) 
    $(CC) $(CFLAGS) -c -o [email protected] $< 

Ошибки Поступило:

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

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

+1

Почему вы не используете системный вызов ['sbrk'] (https://developer.apple.com/library/ios/documentation/System/Conceptual/ManPages_iPhoneOS/man2/brk.2.html), если хотите низкий уровень? Это будет соответствовать вашему использованию 'write' и не должно давать никаких проблем с связыванием. – CRD

+0

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

+0

Возможно, вам стоит взглянуть на 'vm_allocate', Apple показывает пример использования [в этом документе] (https://developer.apple.com/library/ios/documentation/Performance/Conceptual/ManagingMemory/Articles/MemoryAlloc.html) – CRD

ответ

0

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