The bootmaker now defaults to the endian of the host platform.

Fixed style issues.


git-svn-id: file:///srv/svn/repos/haiku/trunk/current@2402 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Axel Dörfler 2003-01-10 11:48:38 +00:00
parent d9f08d808d
commit 1ff1332c77

View File

@ -38,35 +38,36 @@
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <unistd.h> #include <unistd.h>
#include <string.h>
#ifdef sparc #ifdef sparc
#define xBIG_ENDIAN 1 # define xBIG_ENDIAN 1
#endif #endif
#ifdef i386 #ifdef i386
#define xLITTLE_ENDIAN 1 # define xLITTLE_ENDIAN 1
#endif #endif
#ifdef __ppc__ #ifdef __ppc__
#define xBIG_ENDIAN 1 # define xBIG_ENDIAN 1
#endif #endif
#define SWAP32(x) \ #define SWAP32(x) \
((((x) & 0xff) << 24) | (((x) & 0xff00) << 8) | (((x) & 0xff0000) >> 8) | (((x) & 0xff000000) >> 24)) ((((x) & 0xff) << 24) | (((x) & 0xff00) << 8) | (((x) & 0xff0000) >> 8) | (((x) & 0xff000000) >> 24))
#if xBIG_ENDIAN #if xBIG_ENDIAN
#define HOST_TO_BENDIAN32(x) (x) # define HOST_TO_BENDIAN32(x) (x)
#define BENDIAN_TO_HOST32(x) (x) # define BENDIAN_TO_HOST32(x) (x)
#define HOST_TO_LENDIAN32(x) SWAP32(x) # define HOST_TO_LENDIAN32(x) SWAP32(x)
#define LENDIAN_TO_HOST32(x) SWAP32(x) # define LENDIAN_TO_HOST32(x) SWAP32(x)
#endif #endif
#if xLITTLE_ENDIAN #if xLITTLE_ENDIAN
#define HOST_TO_BENDIAN32(x) SWAP32(x) # define HOST_TO_BENDIAN32(x) SWAP32(x)
#define BENDIAN_TO_HOST32(x) SWAP32(x) # define BENDIAN_TO_HOST32(x) SWAP32(x)
#define HOST_TO_LENDIAN32(x) (x) # define HOST_TO_LENDIAN32(x) (x)
#define LENDIAN_TO_HOST32(x) (x) # define LENDIAN_TO_HOST32(x) (x)
#endif #endif
#if !xBIG_ENDIAN && !xLITTLE_ENDIAN #if !xBIG_ENDIAN && !xLITTLE_ENDIAN
#error not sure which endian the host processor is, please edit bootmaker.c # error not sure which endian the host processor is, please edit bootmaker.c
#endif #endif
// ELF stuff // ELF stuff
@ -122,13 +123,18 @@ struct Elf32_Phdr {
}; };
#ifndef O_BINARY #ifndef O_BINARY
#define O_BINARY 0 # define O_BINARY 0
#endif #endif
#define LE 0 #define LE 0
#define BE 1 #define BE 1
// define host endian as default for the target environment
#if xBIG_ENDIAN
static int target_endian = BE;
#else
static int target_endian = LE; static int target_endian = LE;
#endif
#define fix(x) ((target_endian == BE) ? HOST_TO_BENDIAN32(x) : HOST_TO_LENDIAN32(x)) #define fix(x) ((target_endian == BE) ? HOST_TO_BENDIAN32(x) : HOST_TO_LENDIAN32(x))
@ -136,68 +142,75 @@ static int make_sparcboot = 0;
static int strip_debug = 0; static int strip_debug = 0;
static char *strip_binary = "strip"; static char *strip_binary = "strip";
void die(char *s, char *a)
void
die(char *s, char *a)
{ {
fprintf(stderr,"error: "); fprintf(stderr,"error: ");
fprintf(stderr,s,a); fprintf(stderr,s,a);
fprintf(stderr,"\n"); fprintf(stderr,"\n");
exit(1); exit(1);
} }
void *loadfile(char *file, int *size)
{
int fd;
char *data;
struct stat info;
if((fd = open(file,O_BINARY|O_RDONLY)) != -1){ void *
if(fstat(fd,&info)){ loadfile(char *file, int *size)
close(fd); {
*size = 0; int fd;
return NULL; char *data;
} struct stat info;
data = (char *) malloc(info.st_size);
if(read(fd, data, info.st_size) != info.st_size) { if ((fd = open(file, O_BINARY|O_RDONLY)) != -1) {
close(fd); if (fstat(fd, &info)) {
*size = 0; close(fd);
return NULL; *size = 0;
} return NULL;
close(fd); }
*size = info.st_size; data = (char *)malloc(info.st_size);
return data; if (read(fd, data, info.st_size) != info.st_size) {
} close(fd);
*size = 0; *size = 0;
return NULL; return NULL;
}
close(fd);
*size = info.st_size;
return data;
}
*size = 0;
return NULL;
} }
void *loadstripfile(char *file, int *size)
void *
loadstripfile(char *file, int *size)
{ {
char temp[256]; char temp[256];
char cmd[4096]; char cmd[4096];
void *retval; void *retval;
if (strip_debug) {
strcpy(temp, "/tmp/mkboot.XXXXXXXX");
mktemp(temp);
sprintf(cmd, "cp %s %s; %s %s", file, temp, strip_binary, temp);
system(cmd);
if(strip_debug) { retval = loadfile(temp, size);
strcpy(temp, "/tmp/mkboot.XXXXXXXX");
mktemp(temp);
sprintf(cmd, "cp %s %s; %s %s", file, temp, strip_binary, temp);
system(cmd);
retval = loadfile(temp, size); unlink(temp);
} else {
retval = loadfile(file, size);
}
unlink(temp); return retval;
} else {
retval = loadfile(file, size);
}
return retval;
} }
// write a boot block to the head of the dir. // write a boot block to the head of the dir.
// note: the first 0x20 bytes are removed by the sparc prom // note: the first 0x20 bytes are removed by the sparc prom
// which makes the whole file off by 0x20 bytes // which makes the whole file off by 0x20 bytes
/* /*
int writesparcbootblock(int fd, unsigned int blocks) int
writesparcbootblock(int fd, unsigned int blocks)
{ {
unsigned char bb[0x200+0x20]; unsigned char bb[0x200+0x20];
@ -210,32 +223,36 @@ int writesparcbootblock(int fd, unsigned int blocks)
typedef struct _nvpair typedef struct _nvpair
{ {
struct _nvpair *next; struct _nvpair *next;
char *name; char *name;
char *value; char *value;
} nvpair; } nvpair;
typedef struct _section typedef struct _section
{ {
struct _section *next; struct _section *next;
char *name; char *name;
struct _nvpair *firstnv; struct _nvpair *firstnv;
} section; } section;
void print_sections(section *first)
void
print_sections(section *first)
{ {
nvpair *p; nvpair *p;
while(first){ while (first) {
printf("\n[%s]\n",first->name); printf("\n[%s]\n", first->name);
for(p = first->firstnv; p; p = p->next){
printf("%s=%s\n",p->name,p->value); for (p = first->firstnv; p; p = p->next) {
printf("%s=%s\n", p->name, p->value);
} }
first = first->next; first = first->next;
} }
} }
#define stNEWLINE 0 #define stNEWLINE 0
#define stSKIPLINE 1 #define stSKIPLINE 1
#define stHEADER 2 #define stHEADER 2
@ -245,115 +262,123 @@ void print_sections(section *first)
section *first = NULL; section *first = NULL;
section *last = NULL; section *last = NULL;
section *load_ini(char *file) section *
load_ini(char *file)
{ {
char *data,*end; char *data, *end;
int size; int size;
int state = stNEWLINE; int state = stNEWLINE;
section *cur; section *cur;
char *lhs, *rhs;
char *lhs,*rhs;
if (!(data = loadfile(file, &size)))
if(!(data = loadfile(file,&size))){ return NULL;
return NULL;
} end = data+size;
end = data+size;
while (data < end) {
while(data < end){ switch (state) {
switch(state){ case stSKIPLINE:
case stSKIPLINE: if (*data == '\n' || *data == '\r')
if(*data == '\n' || *data == '\r'){ state = stNEWLINE;
state = stNEWLINE;
} data++;
data++; break;
break;
case stNEWLINE:
case stNEWLINE: if (*data == '\n' || *data == '\r') {
if(*data == '\n' || *data == '\r'){ data++;
data++; break;
break; }
}
if(*data == '['){ if (*data == '[') {
lhs = data+1; lhs = data+1;
state = stHEADER; state = stHEADER;
data++; data++;
break; break;
} }
if(*data == '#' || *data <= ' '){
state = stSKIPLINE; if (*data == '#' || *data <= ' ') {
data++; state = stSKIPLINE;
break; data++;
} break;
lhs = data; }
data++; lhs = data;
state = stLHS; data++;
break; state = stLHS;
case stHEADER: break;
if(*data == ']'){ case stHEADER:
cur = (section *) malloc(sizeof(section)); if (*data == ']') {
cur->name = lhs; cur = (section *) malloc(sizeof(section));
cur->firstnv = NULL; cur->name = lhs;
cur->next = NULL; cur->firstnv = NULL;
if(last){ cur->next = NULL;
last->next = cur; if (last) {
last = cur; last->next = cur;
} else { last = cur;
last = first = cur; } else {
} last = first = cur;
*data = 0; }
state = stSKIPLINE; *data = 0;
} state = stSKIPLINE;
data++; }
break; data++;
case stLHS: break;
if(*data == '\n' || *data == '\r'){ case stLHS:
state = stNEWLINE; if (*data == '\n' || *data == '\r')
} state = stNEWLINE;
if(*data == '='){
*data = 0; if (*data == '=') {
rhs = data+1; *data = 0;
state = stRHS; rhs = data+1;
} state = stRHS;
data++; }
continue; data++;
case stRHS: continue;
if(*data == '\n' || *data == '\r'){ case stRHS:
nvpair *p = (nvpair *) malloc(sizeof(nvpair)); if (*data == '\n' || *data == '\r') {
p->name = lhs; nvpair *p = (nvpair *)malloc(sizeof(nvpair));
p->value = rhs; p->name = lhs;
*data = 0; p->value = rhs;
p->next = cur->firstnv; *data = 0;
cur->firstnv = p; p->next = cur->firstnv;
state = stNEWLINE; cur->firstnv = p;
} state = stNEWLINE;
data++; }
break; data++;
} break;
} }
return first; }
return first;
} }
char *getval(section *s, char *name) char *
getval(section *s, char *name)
{ {
nvpair *p; nvpair *p;
for(p = s->firstnv; p; p = p->next){ for (p = s->firstnv; p; p = p->next) {
if(!strcmp(p->name,name)) return p->value; if (!strcmp(p->name, name))
} return p->value;
return NULL; }
return NULL;
} }
char *getvaldef(section *s, char *name, char *def)
char *
getvaldef(section *s, char *name, char *def)
{ {
nvpair *p; nvpair *p;
for(p = s->firstnv; p; p = p->next){ for (p = s->firstnv; p; p = p->next) {
if(!strcmp(p->name,name)) return p->value; if (!strcmp(p->name, name))
} return p->value;
return def; }
return def;
} }
Elf32_Addr elf_find_entry(void *buf, int size)
Elf32_Addr
elf_find_entry(void *buf, int size)
{ {
struct Elf32_Ehdr *header; struct Elf32_Ehdr *header;
struct Elf32_Phdr *pheader; struct Elf32_Phdr *pheader;
@ -363,23 +388,23 @@ Elf32_Addr elf_find_entry(void *buf, int size)
#define SWAPIT(x) ((byte_swap) ? SWAP32(x) : (x)) #define SWAPIT(x) ((byte_swap) ? SWAP32(x) : (x))
if(memcmp(cbuf, ELF_MAGIC, sizeof(ELF_MAGIC)-1) != 0) if (memcmp(cbuf, ELF_MAGIC, sizeof(ELF_MAGIC)-1) != 0)
return 0; return 0;
if(cbuf[EI_CLASS] != ELFCLASS32) if (cbuf[EI_CLASS] != ELFCLASS32)
return 0; return 0;
byte_swap = 0; byte_swap = 0;
#if xBIG_ENDIAN #if xBIG_ENDIAN
if(cbuf[EI_DATA] == ELFDATA2LSB) { if (cbuf[EI_DATA] == ELFDATA2LSB) {
byte_swap = 1; byte_swap = 1;
} }
#else #else
if(cbuf[EI_DATA] == ELFDATA2MSB) { if (cbuf[EI_DATA] == ELFDATA2MSB) {
byte_swap = 1; byte_swap = 1;
} }
#endif #endif
header = (struct Elf32_Ehdr *)cbuf; header = (struct Elf32_Ehdr *)cbuf;
pheader = (struct Elf32_Phdr *)&cbuf[SWAPIT(header->e_phoff)]; pheader = (struct Elf32_Phdr *)&cbuf[SWAPIT(header->e_phoff)];
@ -389,175 +414,193 @@ Elf32_Addr elf_find_entry(void *buf, int size)
#undef SWAPIT #undef SWAPIT
#define centry bdir.bd_entry[c] #define centry bdir.bd_entry[c]
void makeboot(section *s, char *outfile) void
makeboot(section *s, char *outfile)
{ {
int fd; int fd;
void *rawdata[64]; void *rawdata[64];
int rawsize[64]; int rawsize[64];
char fill[4096]; char fill[4096];
boot_dir bdir; boot_dir bdir;
int i,c; int i,c;
int nextpage = 1; /* page rel offset of next loaded object */ int nextpage = 1; /* page rel offset of next loaded object */
memset(fill,0,4096); memset(fill, 0, 4096);
memset(&bdir, 0, 4096);
memset(&bdir, 0, 4096);
for(i=0;i<64;i++){
rawdata[i] = NULL;
rawsize[i] = 0;
}
c = 1; for (i = 0; i < 64; i++) {
rawdata[i] = NULL;
rawsize[i] = 0;
}
bdir.bd_entry[0].be_type = fix(BE_TYPE_DIRECTORY); c = 1;
bdir.bd_entry[0].be_size = fix(1);
bdir.bd_entry[0].be_vsize = fix(1);
rawdata[0] = (void *) &bdir;
rawsize[0] = 4096;
strcpy(bdir.bd_entry[0].be_name,"SBBB/Directory");
while(s){ bdir.bd_entry[0].be_type = fix(BE_TYPE_DIRECTORY);
char *type = getvaldef(s,"type","NONE"); bdir.bd_entry[0].be_size = fix(1);
char *file = getval(s,"file"); bdir.bd_entry[0].be_vsize = fix(1);
int vsize; rawdata[0] = (void *) &bdir;
int size; rawsize[0] = 4096;
struct stat statbuf;
if(!type) die("section %s has no type",s->name);
strncpy(centry.be_name,s->name, BOOTDIR_NAMELEN); strcpy(bdir.bd_entry[0].be_name,"SBBB/Directory");
centry.be_name[BOOTDIR_NAMELEN - 1] = 0;
if(!file) die("section %s has no file",s->name); while (s) {
rawdata[c]= ((strcmp(type, "elf32")==0)?loadstripfile:loadfile)(file,&rawsize[c]); char *type = getvaldef(s, "type", "NONE");
if(!rawdata[c]) char *file = getval(s, "file");
die("cannot load \"%s\"",file); int vsize;
int size;
struct stat statbuf;
if(stat(file,&statbuf)) if (!type)
die("cannot stat \"%s\"",file); die("section %s has no type", s->name);
vsize = statbuf.st_size;
centry.be_size = rawsize[c] / 4096 + (rawsize[c] % 4096 ? 1 : 0);
centry.be_vsize =
(vsize < centry.be_size) ? centry.be_size : vsize;
centry.be_offset = nextpage; strncpy(centry.be_name,s->name, BOOTDIR_NAMELEN);
nextpage += centry.be_size; centry.be_name[BOOTDIR_NAMELEN - 1] = 0;
centry.be_size = fix(centry.be_size); if (!file)
centry.be_vsize = fix(centry.be_vsize); die("section %s has no file", s->name);
centry.be_offset = fix(centry.be_offset);
if(!strcmp(type,"boot")){
centry.be_type = fix(BE_TYPE_BOOTSTRAP);
centry.be_code_vaddr = fix(atoi(getvaldef(s,"vaddr","0")));
centry.be_code_ventr = fix(atoi(getvaldef(s,"ventry","0")));
}
if(!strcmp(type,"code")){
centry.be_type = fix(BE_TYPE_CODE);
centry.be_code_vaddr = fix(atoi(getvaldef(s,"vaddr","0")));
centry.be_code_ventr = fix(atoi(getvaldef(s,"ventry","0")));
}
if(!strcmp(type,"data")){
centry.be_type = fix(BE_TYPE_DATA);
}
if(!strcmp(type,"elf32")){
centry.be_type = fix(BE_TYPE_ELF32);
centry.be_code_vaddr = 0;
centry.be_code_ventr = fix(elf_find_entry(rawdata[c], rawsize[c]));
}
if(centry.be_type == BE_TYPE_NONE){ rawdata[c] = ((strcmp(type, "elf32")==0) ? loadstripfile : loadfile)(file,&rawsize[c]);
die("unrecognized section type \"%s\"",type); if (!rawdata[c])
} die("cannot load \"%s\"",file);
c++; if (stat(file,&statbuf))
s = s->next; die("cannot stat \"%s\"",file);
vsize = statbuf.st_size;
if(c == BOOTDIR_MAX_ENTRIES) die("too many sections (>63)",NULL);
}
if((fd = open(outfile, O_BINARY|O_WRONLY|O_CREAT|O_TRUNC, 0666)) < 0) { centry.be_size = rawsize[c] / 4096 + (rawsize[c] % 4096 ? 1 : 0);
die("cannot write to \"%s\"",outfile); centry.be_vsize = (vsize < centry.be_size) ? centry.be_size : vsize;
}
centry.be_offset = nextpage;
nextpage += centry.be_size;
centry.be_size = fix(centry.be_size);
centry.be_vsize = fix(centry.be_vsize);
centry.be_offset = fix(centry.be_offset);
if (!strcmp(type,"boot")) {
centry.be_type = fix(BE_TYPE_BOOTSTRAP);
centry.be_code_vaddr = fix(atoi(getvaldef(s, "vaddr", "0")));
centry.be_code_ventr = fix(atoi(getvaldef(s, "ventry", "0")));
}
if(!strcmp(type,"code")){
centry.be_type = fix(BE_TYPE_CODE);
centry.be_code_vaddr = fix(atoi(getvaldef(s, "vaddr", "0")));
centry.be_code_ventr = fix(atoi(getvaldef(s, "ventry", "0")));
}
if (!strcmp(type, "data"))
centry.be_type = fix(BE_TYPE_DATA);
if (!strcmp(type, "elf32")) {
centry.be_type = fix(BE_TYPE_ELF32);
centry.be_code_vaddr = 0;
centry.be_code_ventr = fix(elf_find_entry(rawdata[c], rawsize[c]));
}
if (centry.be_type == BE_TYPE_NONE)
die("unrecognized section type \"%s\"", type);
c++;
s = s->next;
if (c == BOOTDIR_MAX_ENTRIES)
die("too many sections (>63)",NULL);
}
if ((fd = open(outfile, O_BINARY|O_WRONLY|O_CREAT|O_TRUNC, 0666)) < 0)
die("cannot write to \"%s\"",outfile);
/* XXX - Hope this isn't needed :( /* XXX - Hope this isn't needed :(
if(make_sparcboot) { if (make_sparcboot)
writesparcbootblock(fd, nextpage+1); writesparcbootblock(fd, nextpage + 1);
}
*/ */
for(i=0;i<c;i++){ for (i = 0; i < c; i++) {
write(fd, rawdata[i], rawsize[i]); write(fd, rawdata[i], rawsize[i]);
if(rawsize[i]%4096) if (rawsize[i] % 4096)
write(fd, fill, 4096 - (rawsize[i]%4096)); write(fd, fill, 4096 - (rawsize[i]%4096));
} }
close(fd); close(fd);
} }
int main(int argc, char **argv)
void
usage(char *name)
{
char *programName = strrchr(name, '/');
if (programName == NULL)
programName = name;
else
programName++;
fprintf(stderr,
"usage: %s [--littleendian] [--bigendian ] [ --strip-binary <binary ] [ --strip-debug] [ --sparc | -s ] [ <inifile> ... ] -o <bootfile>\n"
"\tdefaults to "
#if xBIG_ENDIAN
"\"big-endian\""
#else
"\"little-endian\""
#endif
" on this platform\n", programName);
exit(1);
}
int
main(int argc, char **argv)
{ {
char *file = NULL; char *file = NULL;
section *s; char *programName = argv[0];
section *s;
if(argc < 2){
usage: if (argc < 2)
fprintf(stderr,"usage: %s [--littleendian (default)] [--bigendian ] [ --strip-binary <binary ] [ --strip-debug] [ --sparc | -s ] [ <inifile> ... ] -o <bootfile>\n",argv[0]); usage(programName);
return 1;
}
argc--; argc--;
argv++; argv++;
while(argc){ while (argc){
if(!strcmp(*argv,"--sparc")) { if (!strcmp(*argv,"--sparc")) {
make_sparcboot = 1; make_sparcboot = 1;
} else if(!strcmp(*argv, "--bigendian")) { } else if (!strcmp(*argv, "--bigendian")) {
target_endian = BE; target_endian = BE;
} else if(!strcmp(*argv,"-o")) { } else if (!strcmp(*argv,"-o")) {
argc--; argc--;
argv++; argv++;
if(argc) { if (argc)
file = *argv; file = *argv;
} else { else
goto usage; usage(programName);
} } else if (!strcmp(*argv, "--strip-binary")) {
} else if(!strcmp(*argv, "--strip-binary")) {
argc--; argc--;
argv++; argv++;
if(argc) { if (argc)
strip_binary = *argv; strip_binary = *argv;
} else { else
goto usage; usage(programName);
} } else if (!strcmp(*argv, "--strip-debug")) {
} else if(!strcmp(*argv, "--strip-debug")) {
strip_debug = 1; strip_debug = 1;
} else { } else {
if(load_ini(*argv) == NULL) { if (load_ini(*argv) == NULL)
fprintf(stderr,"warning: cannot load '%s'\n",*argv); fprintf(stderr, "warning: cannot load '%s'\n", *argv);
}
} }
argc--; argc--;
argv++; argv++;
} }
if((argc > 3) && !strcmp(argv[3],"-sparc")){
make_sparcboot = 1;
}
if(!file){ if ((argc > 3) && !strcmp(argv[3], "-sparc"))
make_sparcboot = 1;
if (!file){
fprintf(stderr,"error: no output specified\n"); fprintf(stderr,"error: no output specified\n");
goto usage; usage(programName);
} }
if(!first){ if (!first){
fprintf(stderr,"error: no data to write?!\n"); fprintf(stderr, "error: no data to write?!\n");
goto usage; usage(programName);
} }
makeboot(first,file); makeboot(first, file);
return 0; return 0;
} }