mirror of
https://github.com/mikpe/pdp10-tools.git
synced 2026-01-11 23:53:19 +00:00
255 lines
6.5 KiB
C
255 lines
6.5 KiB
C
/*
|
|
* gen-test1.c -- generate test1.o for readelf
|
|
* Copyright (C) 2013-2015 Mikael Pettersson
|
|
*
|
|
* This file is part of pdp10-tools.
|
|
*
|
|
* pdp10-tools is free software: you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation, either version 3 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* pdp10-tools is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with pdp10-tools. If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
#include <errno.h>
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
#include "pdp10-elf36.h"
|
|
#include "pdp10-stdio.h"
|
|
|
|
/*
|
|
* Layout (mirroring a minimal x86 ELF32 file with empty .data and .bss omitted):
|
|
*
|
|
* 0:
|
|
* - ELF Header (52 nonets, 13 words)
|
|
* 52:
|
|
* - Contents of .text (12 nonets, 3 words)
|
|
* 64:
|
|
* - Contents of .shstrtab: "", ".symtab", ".strtab", ".shstrtab", ".text"
|
|
* (33 nonets padded to 36 nonets, 9 words)
|
|
* 100:
|
|
* - Section headers:
|
|
* + [0] empty
|
|
* + [1] .text
|
|
* + [2] .shstrtab
|
|
* + [3] .symtab
|
|
* + [4] .strtab
|
|
* (200 (5 * 40) nonets, 50 words)
|
|
* 300:
|
|
* - Contents of .symtab: (undef), function global .text "start"
|
|
* (32 (2 * 16) nonets, 8 words)
|
|
* 332:
|
|
* - Contents of .strtab: "", "start"
|
|
* (7 nonets padded to 8 nonets, 2 words)
|
|
* 340:
|
|
* - end of file
|
|
*/
|
|
|
|
static int write_elf(PDP10_FILE *pdp10fp)
|
|
{
|
|
enum {
|
|
/* size of start and .text */
|
|
TEXT_SIZE_start = 12,
|
|
TEXT_SIZE = TEXT_SIZE_start,
|
|
|
|
/* .shstrtab indices and size */
|
|
SHSTRTAB_IX_symtab = 1,
|
|
SHSTRTAB_IX_strtab = 9,
|
|
SHSTRTAB_IX_shstrtab = 17,
|
|
SHSTRTAB_IX_text = 27,
|
|
SHSTRTAB_SIZE = 36,
|
|
|
|
/* .strtab indices and size */
|
|
STRTAB_IX_start = 1,
|
|
STRTAB_SIZE = 8,
|
|
|
|
/* section header indices and size */
|
|
SHTAB_IX_text = 1,
|
|
SHTAB_IX_shstrtab = 2,
|
|
SHTAB_IX_strtab = 3,
|
|
SHTAB_NR = 5,
|
|
|
|
/* .symtab indices and size */
|
|
SYMTAB_IX_LAST_LOCAL = 0,
|
|
SYMTAB_NR = 2,
|
|
SYMTAB_SIZE = SYMTAB_NR * ELF36_SYM_SIZEOF,
|
|
|
|
/* file offsets */
|
|
FILE_OFFSET_TEXT = ELF36_EHDR_SIZEOF,
|
|
FILE_OFFSET_SHSTRTAB = FILE_OFFSET_TEXT + TEXT_SIZE,
|
|
FILE_OFFSET_SHTAB = FILE_OFFSET_SHSTRTAB + SHSTRTAB_SIZE,
|
|
FILE_OFFSET_SYMTAB = FILE_OFFSET_SHTAB + (SHTAB_NR * ELF36_SHDR_SIZEOF),
|
|
FILE_OFFSET_STRTAB = FILE_OFFSET_SYMTAB + SYMTAB_SIZE,
|
|
};
|
|
static const pdp10_uint36_t text[3] = {
|
|
/* start: */
|
|
PDP10_UINT36_C(0201040000000), /* MOVEI 1,0 ; exit status = 0 */
|
|
PDP10_UINT36_C(0104000000136), /* JSYS 0136 ; SYS_exit_group */
|
|
PDP10_UINT36_C(0254200000000), /* HALT */
|
|
};
|
|
static const pdp10_uint9_t shstrtab[36] = {
|
|
'\0', '.', 's', 'y', 'm', 't', 'a', 'b', '\0', '.', 's', 't', 'r', 't', 'a', 'b',
|
|
'\0', '.', 's', 'h', 's', 't', 'r', 't', 'a', 'b', '\0', '.', 't', 'e', 'x', 't',
|
|
'\0', '\0', '\0', '\0',
|
|
};
|
|
static const pdp10_uint9_t strtab[8] = {
|
|
'\0', 's', 't', 'a', 'r', 't', '\0', '\0'
|
|
};
|
|
static const Elf36_Shdr shtab[5] = {
|
|
[0] = { /* (empty) */
|
|
.sh_name = 0,
|
|
.sh_type = SHT_NULL,
|
|
.sh_flags = 0,
|
|
.sh_addr = 0,
|
|
.sh_offset = 0,
|
|
.sh_size = 0,
|
|
.sh_link = 0,
|
|
.sh_info = 0,
|
|
.sh_addralign = 0,
|
|
.sh_entsize = 0,
|
|
},
|
|
[1] = { /* .text */
|
|
.sh_name = SHSTRTAB_IX_text,
|
|
.sh_type = SHT_PROGBITS,
|
|
.sh_flags = SHF_ALLOC | SHF_EXECINSTR,
|
|
.sh_addr = 0,
|
|
.sh_offset = FILE_OFFSET_TEXT,
|
|
.sh_size = TEXT_SIZE,
|
|
.sh_link = 0,
|
|
.sh_info = 0,
|
|
.sh_addralign = 4,
|
|
.sh_entsize = 0,
|
|
},
|
|
[2] = { /* .shstrtab */
|
|
.sh_name = SHSTRTAB_IX_shstrtab,
|
|
.sh_type = SHT_STRTAB,
|
|
.sh_flags = 0,
|
|
.sh_addr = 0,
|
|
.sh_offset = FILE_OFFSET_SHSTRTAB,
|
|
.sh_size = SHSTRTAB_SIZE,
|
|
.sh_link = 0,
|
|
.sh_info = 0,
|
|
.sh_addralign = 1,
|
|
.sh_entsize = 0,
|
|
},
|
|
[3] = { /* .strtab */
|
|
.sh_name = SHSTRTAB_IX_strtab,
|
|
.sh_type = SHT_STRTAB,
|
|
.sh_flags = 0,
|
|
.sh_addr = 0,
|
|
.sh_offset = FILE_OFFSET_STRTAB,
|
|
.sh_size = STRTAB_SIZE,
|
|
.sh_link = 0,
|
|
.sh_info = 0,
|
|
.sh_addralign = 1,
|
|
.sh_entsize = 0,
|
|
},
|
|
[4] = { /* .symtab */
|
|
.sh_name = SHSTRTAB_IX_symtab,
|
|
.sh_type = SHT_SYMTAB,
|
|
.sh_flags = 0,
|
|
.sh_addr = 0,
|
|
.sh_offset = FILE_OFFSET_SYMTAB,
|
|
.sh_size = SYMTAB_SIZE,
|
|
.sh_link = SHTAB_IX_strtab,
|
|
.sh_info = SYMTAB_IX_LAST_LOCAL + 1,
|
|
.sh_addralign = 4,
|
|
.sh_entsize = ELF36_SYM_SIZEOF,
|
|
},
|
|
};
|
|
static const Elf36_Sym symtab[2] = {
|
|
[0] = { /* (empty) */
|
|
.st_name = 0,
|
|
.st_value = 0,
|
|
.st_size = 0,
|
|
.st_info = ELF36_ST_INFO(STB_LOCAL, STT_NOTYPE),
|
|
.st_other = 0,
|
|
.st_shndx = SHN_UNDEF,
|
|
},
|
|
[1] = { /* start */
|
|
.st_name = STRTAB_IX_start,
|
|
.st_value = 0,
|
|
.st_size = TEXT_SIZE_start,
|
|
.st_info = ELF36_ST_INFO(STB_GLOBAL, STT_FUNC),
|
|
.st_other = STV_DEFAULT,
|
|
.st_shndx = SHTAB_IX_text,
|
|
},
|
|
};
|
|
static const Elf36_Ehdr ehdr = {
|
|
.e_ident[EI_MAG0] = ELFMAG0,
|
|
.e_ident[EI_MAG1] = ELFMAG1,
|
|
.e_ident[EI_MAG2] = ELFMAG2,
|
|
.e_ident[EI_MAG3] = ELFMAG3,
|
|
.e_ident[EI_CLASS] = ELFCLASS36,
|
|
.e_ident[EI_DATA] = ELFDATA2MSB,
|
|
.e_ident[EI_VERSION] = EV_CURRENT,
|
|
.e_ident[EI_OSABI] = ELFOSABI_NONE,
|
|
.e_ident[EI_ABIVERSION] = 0,
|
|
.e_ident[EI_PAD ... EI_NIDENT - 1] = 0,
|
|
.e_type = ET_REL,
|
|
.e_machine = EM_PDP10,
|
|
.e_version = EV_CURRENT,
|
|
.e_entry = 0,
|
|
.e_phoff = 0,
|
|
.e_shoff = FILE_OFFSET_SHTAB,
|
|
.e_flags = 0,
|
|
.e_ehsize = ELF36_EHDR_SIZEOF,
|
|
.e_phentsize = 0,
|
|
.e_phnum = 0,
|
|
.e_shentsize = ELF36_SHDR_SIZEOF,
|
|
.e_shnum = SHTAB_NR,
|
|
.e_shstrndx = SHTAB_IX_shstrtab,
|
|
};
|
|
unsigned int i;
|
|
|
|
if (pdp10_elf36_write_ehdr(pdp10fp, &ehdr) < 0)
|
|
return 1;
|
|
|
|
for (i = 0; i < 3; ++i)
|
|
if (pdp10_elf36_write_uint36(pdp10fp, text[i]) < 0)
|
|
return -1;
|
|
|
|
for (i = 0; i < 36; ++i)
|
|
if (pdp10_elf36_write_uint9(pdp10fp, shstrtab[i]) < 0)
|
|
return -1;
|
|
|
|
for (i = 0; i < 5; ++i)
|
|
if (pdp10_elf36_write_shdr(pdp10fp, &shtab[i]) < 0)
|
|
return -1;
|
|
|
|
for (i = 0; i < 2; ++i)
|
|
if (pdp10_elf36_write_sym(pdp10fp, &symtab[i]) < 0)
|
|
return -1;
|
|
|
|
for (i = 0; i < 8; ++i)
|
|
if (pdp10_elf36_write_uint9(pdp10fp, strtab[i]) < 0)
|
|
return -1;
|
|
|
|
return 0;
|
|
}
|
|
|
|
int main(void)
|
|
{
|
|
PDP10_FILE *pdp10fp;
|
|
|
|
pdp10fp = pdp10_fopen("test1.o", "wb");
|
|
if (!pdp10fp) {
|
|
fprintf(stderr, "failed to open %s: %s\n", "test1.o", strerror(errno));
|
|
return 1;
|
|
}
|
|
|
|
if (write_elf(pdp10fp) < 0) {
|
|
fprintf(stderr, "failed to write ELF data: %s\n", strerror(errno));
|
|
return 1;
|
|
}
|
|
|
|
pdp10_fclose(pdp10fp);
|
|
return 0;
|
|
}
|