#ifndef RLD
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <limits.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <mach/mach.h>
#include <libc.h>
#include "stuff/bool.h"
#include "stuff/errors.h"
#include "stuff/allocate.h"
#include "stuff/guess_short_name.h"
#include "stuff/seg_addr_table.h"
struct seg_addr_table *
parse_default_seg_addr_table(
char **seg_addr_table_name,
uint32_t *table_size)
{
#ifdef __GONZO_BUNSEN_BEAKER__
*seg_addr_table_name = "/Local/Developer/seg_addr_table";
#else
*seg_addr_table_name = "/AppleInternal/Developer/seg_addr_table";
#endif
return(parse_seg_addr_table(*seg_addr_table_name,
"default", "segment address table", table_size));
}
struct seg_addr_table *
parse_seg_addr_table(
char *file_name,
char *flag,
char *argument,
uint32_t *table_size)
{
int fd;
struct stat stat_buf;
uint32_t j, k, file_size, seg_addr_table_size, line;
char *file_addr, *endp;
struct seg_addr_table *new_seg_addr_table;
if((fd = open(file_name, O_RDONLY, 0)) == -1)
system_fatal("Can't open: %s for %s %s",
file_name, flag, argument);
if(fstat(fd, &stat_buf) == -1)
system_fatal("Can't stat file: %s for %s %s",
file_name, flag, argument);
file_addr = NULL;
if(stat_buf.st_size != 0){
file_addr = mmap(0, stat_buf.st_size, PROT_READ|PROT_WRITE,
MAP_FILE|MAP_PRIVATE, fd, 0);
if((intptr_t)file_addr == -1)
system_error("can't map file: %s for %s %s", file_name, flag,
argument);
}
else
fatal("Empty file: %s for %s %s", file_name, flag, argument);
close(fd);
file_size = stat_buf.st_size;
if(file_addr[file_size - 1] != '\n')
fatal("file: %s for %s %s does not end in new line",
file_name, flag, argument);
seg_addr_table_size = 0;
for(j = 1; j < file_size; j++){
if(file_addr[j] == '\n'){
seg_addr_table_size++;
}
}
seg_addr_table_size++;
new_seg_addr_table = allocate(sizeof(struct seg_addr_table) *
seg_addr_table_size);
k = 0;
line = 1;
for(j = 0; j < file_size; ){
if(file_addr[j] == '#'){
j++;
while(file_addr[j] != '\n')
j++;
continue;
}
while(file_addr[j] == ' ' || file_addr[j] == '\t')
j++;
if(file_addr[j] == '\n'){
j++;
line++;
continue;
}
new_seg_addr_table[k].seg1addr =
strtoul(file_addr + j, &endp, 16);
if(endp == NULL)
fatal("improper hexadecimal number on line %u in "
"file: %s for %s %s", j, file_name, flag, argument);
j = endp - file_addr;
if(j == file_size)
fatal("missing library install name on line %u in file: "
"%s for %s %s", j, file_name, flag, argument);
while(file_addr[j] == ' ' || file_addr[j] == '\t')
j++;
if(file_addr[j] == '\n')
fatal("missing library install name on line %u in file: "
"%s for %s %s", j, file_name, flag, argument);
new_seg_addr_table[k].segs_read_write_addr =
strtoul(file_addr + j, &endp, 16);
if(endp == NULL || endp == file_addr + j){
new_seg_addr_table[k].split = FALSE;
new_seg_addr_table[k].segs_read_write_addr = UINT_MAX;
}
else{
j = endp - file_addr;
new_seg_addr_table[k].split = TRUE;
new_seg_addr_table[k].segs_read_only_addr =
new_seg_addr_table[k].seg1addr;
new_seg_addr_table[k].seg1addr = UINT_MAX;
while(file_addr[j] == ' ' || file_addr[j] == '\t')
j++;
}
new_seg_addr_table[k].install_name = file_addr + j;
new_seg_addr_table[k].line = line;
k++;
while(file_addr[j] != '\n')
j++;
file_addr[j] = '\0';
line++;
j++;
}
new_seg_addr_table[k].install_name = NULL;
new_seg_addr_table[k].seg1addr = 0;
new_seg_addr_table[k].split = FALSE;
new_seg_addr_table[k].segs_read_only_addr = UINT_MAX;
new_seg_addr_table[k].segs_read_write_addr = UINT_MAX;
new_seg_addr_table[k].line = line;
*table_size = k;
return(new_seg_addr_table);
}
struct seg_addr_table *
search_seg_addr_table(
struct seg_addr_table *seg_addr_table,
char *install_name)
{
struct seg_addr_table *p;
if(seg_addr_table == NULL)
return(NULL);
for(p = seg_addr_table; p->install_name != NULL; p++){
if(strcmp(p->install_name, install_name) == 0)
return(p);
}
return(NULL);
}
void
process_seg_addr_table(
char *file_name,
FILE *out_fp,
char *comment_prefix,
void (*processor)(struct seg_addr_table *entry, FILE *out_fp, void *cookie),
void *cookie)
{
int fd;
struct stat stat_buf;
uint32_t i, file_size, line, comment_prefix_length;
char *file_addr, *endp;
struct seg_addr_table entry;
file_addr = NULL;
if((fd = open(file_name, O_RDONLY, 0)) == -1)
system_fatal("can't open file: %s", file_name);
if(fstat(fd, &stat_buf) == -1)
system_fatal("can't stat file: %s", file_name);
if(stat_buf.st_size != 0){
file_addr = mmap(0, stat_buf.st_size, PROT_READ|PROT_WRITE,
MAP_FILE|MAP_PRIVATE, fd, 0);
if((intptr_t)file_addr == -1)
system_error("can't map file: %s", file_name);
}
else
fatal("empty file: %s ", file_name);
close(fd);
file_size = stat_buf.st_size;
if(file_addr[file_size - 1] != '\n')
fatal("file: %s does not end in new line", file_name);
line = 1;
comment_prefix_length = strlen(comment_prefix);
for(i = 0; i < file_size; ){
if(file_addr[i] == '#'){
if(strncmp(comment_prefix, file_addr + i + 1,
comment_prefix_length) == 0){
i++;
while(file_addr[i] != '\n')
i++;
if(file_addr[i] == '\n'){
i++;
line++;
}
continue;
}
fputc(file_addr[i], out_fp);
i++;
while(file_addr[i] != '\n'){
fputc(file_addr[i], out_fp);
i++;
}
continue;
}
while(file_addr[i] == ' ' || file_addr[i] == '\t'){
fputc(file_addr[i], out_fp);
i++;
}
if(file_addr[i] == '\n'){
fputc(file_addr[i], out_fp);
i++;
line++;
continue;
}
entry.seg1addr = strtoul(file_addr + i, &endp, 16);
if(endp == NULL)
fatal("improper hexadecimal number on line %u in file: %s",
line, file_name);
i = endp - file_addr;
if(i == file_size)
fatal("missing library install name on line %u in file: %s",
line, file_name);
while(file_addr[i] == ' ' || file_addr[i] == '\t')
i++;
if(file_addr[i] == '\n')
fatal("missing library install name on line %u in file: %s",
line, file_name);
entry.segs_read_write_addr = strtoul(file_addr + i, &endp, 16);
if(endp == NULL || endp == file_addr + i){
entry.split = FALSE;
entry.segs_read_write_addr = UINT_MAX;
}
else{
i = endp - file_addr;
entry.split = TRUE;
entry.segs_read_only_addr = entry.seg1addr;
entry.seg1addr = UINT_MAX;
while(file_addr[i] == ' ' || file_addr[i] == '\t')
i++;
}
entry.install_name = file_addr + i;
entry.line = line;
while(file_addr[i] != '\n')
i++;
file_addr[i] = '\0';
processor(&entry, out_fp, cookie);
line++;
i++;
}
}
#endif