Page 3 of 6

Re: How to compile a flat position-independent binary with G

Posted: Tue Nov 10, 2015 2:51 am
by iansjack
onlyonemac wrote:
iansjack wrote:Well, good luck.

I think you have been given enough information, and advice, as to how to solve your problem. Now it's up to you to use that information wisely.
No, I refuse to use ELF just because you say so. Other people have used flat binaries and I will too. They have their place and their purpose, and their purpose is for those who want to write an operating system their own way. I don't care if ELF is easier, more standard, or whatever else. I have a plan for how I want to write my operating system and I will write it my way.

Now maybe someone else would like to help me with why my code won't compile WITHOUT first insisting that I must write my operating system their way rather than my own.
Calm down! I'm not, now, suggesting that you use ELF or even that you use a cross-compiler. Please, do things your own way.

What I am saying is that you have now been given plenty of information about your problem so do the work and solve it rather than continuing to ask others to do the work for you.

Re: How to compile a flat position-independent binary with G

Posted: Tue Nov 10, 2015 2:55 am
by iansjack
gerryg400 wrote:I'm not sure whether you realise but gcc executes both the compiler and linker. It seems then that you are linking twice.
No.

The OP uses the -c switch in his invocation of gcc so it is only producing an object file, not linking.

Re: How to compile a flat position-independent binary with G

Posted: Tue Nov 10, 2015 2:58 am
by gerryg400
Ah yes. I missed that.

Re: How to compile a flat position-independent binary with G

Posted: Tue Nov 10, 2015 3:06 am
by onlyonemac
@gerryg400: yeah I meant to say linking. I was using the term "compiling" to refer to the complete process from source code to final binary, but yes it is at the linking stage that it fails.

Re: How to compile a flat position-independent binary with G

Posted: Tue Nov 10, 2015 3:13 am
by iansjack
One final point for you to think about. To quote from the gcc manual:
-fpic

Generate position-independent code (PIC) suitable for use in a shared library, if supported for the target machine. Such code accesses all constant addresses through a global offset table (GOT). The dynamic loader resolves the GOT entries when the program starts (the dynamic loader is not part of GCC; it is part of the operating system). If the GOT size for the linked executable exceeds a machine-specific maximum size, you get an error message from the linker indicating that -fpic does not work; in that case, recompile with -fPIC instead. (These maximums are 8k on the SPARC and 32k on the m68k and RS/6000. The x86 has no such limit.)

Position-independent code requires special support, and therefore works only on certain machines. For the x86, GCC supports PIC for System V but not for the Sun 386i. Code generated for the IBM RS/6000 is always position-independent.
Think about it. How does that fit in with what you are trying to do? And note in particular "the dynamic loader is not part of GCC; it is part of the operating system". So have you implemented this dynamic linker in your OS? And what are the implications of throwing away the metadata in the ELF file?

"Position-independent code requires special support".

Re: How to compile a flat position-independent binary with G

Posted: Tue Nov 10, 2015 6:33 am
by onlyonemac
iansjack wrote:One final point for you to think about. To quote from the gcc manual:
-fpic

Generate position-independent code (PIC) suitable for use in a shared library, if supported for the target machine. Such code accesses all constant addresses through a global offset table (GOT). The dynamic loader resolves the GOT entries when the program starts (the dynamic loader is not part of GCC; it is part of the operating system). If the GOT size for the linked executable exceeds a machine-specific maximum size, you get an error message from the linker indicating that -fpic does not work; in that case, recompile with -fPIC instead. (These maximums are 8k on the SPARC and 32k on the m68k and RS/6000. The x86 has no such limit.)

Position-independent code requires special support, and therefore works only on certain machines. For the x86, GCC supports PIC for System V but not for the Sun 386i. Code generated for the IBM RS/6000 is always position-independent.
Think about it. How does that fit in with what you are trying to do? And note in particular "the dynamic loader is not part of GCC; it is part of the operating system". So have you implemented this dynamic linker in your OS? And what are the implications of throwing away the metadata in the ELF file?

"Position-independent code requires special support".
Firstly I am not using -fPIC, I am using -fPIE. Besides, I'm not using any global addresses in that function so I don't know why it's complaining about that function and the GOT.

Re: How to compile a flat position-independent binary with G

Posted: Tue Nov 10, 2015 9:25 am
by iansjack
You obviously read the documentation which tells you that -fPIE acts similarly to -fpic, -fPIC, and -fpie. As the compiler is trying to produce a GOT you may be mistaken in believing that you are creating no constant addresses. Have you inspected the object file, as I suggested, to see where the GOT is being referred to? It's probably more productive than guessing.

Re: How to compile a flat position-independent binary with G

Posted: Tue Nov 10, 2015 12:30 pm
by onlyonemac
iansjack wrote:You obviously read the documentation which tells you that -fPIE acts similarly to -fpic, -fPIC, and -fpie. As the compiler is trying to produce a GOT you may be mistaken in believing that you are creating no constant addresses. Have you inspected the object file, as I suggested, to see where the GOT is being referred to? It's probably more productive than guessing.
I was under the impression that:
  • the GOT is produced/modified/whatever by the binary loader to match the location in memory where the binary is loaded
  • binaries produced with -fPIC require this kind of modification after loading whereas binaries produced with -fPIE don't require modification
. And I have inspected the object file and there's a call to the address of the call instruction plus one (such calls, I have gathered, have got something to do with the linker) in each of the functions for which the linker is returning errors, however I don't understand why those calls are needed. Here is the object dump for one of them (the label "output_seq" is defined later in the object file):

Code: Select all

00000000 <start>:
   0:   55                      push   %ebp
   1:   89 e5                   mov    %esp,%ebp
   3:   53                      push   %ebx
   4:   83 ec 04                sub    $0x4,%esp
   7:   e8 fc ff ff ff          call   8 <start+0x8>
   c:   81 c3 02 00 00 00       add    $0x2,%ebx
  12:   83 ec 0c                sub    $0xc,%esp
  15:   8d 83 00 00 00 00       lea    0x0(%ebx),%eax
  1b:   50                      push   %eax
  1c:   e8 b0 03 00 00          call   3d1 <output_seq>
  21:   83 c4 10                add    $0x10,%esp
  24:   8b 5d fc                mov    -0x4(%ebp),%ebx
  27:   c9                      leave  
  28:   c3                      ret
and the corresponding source code:

Code: Select all

void start()
{
        output_seq("sl");
}
As far as I'm concerned, just push the string onto the stack and pass a pointer. No global addresses needed there.

Re: How to compile a flat position-independent binary with G

Posted: Tue Nov 10, 2015 1:14 pm
by Schol-R-LEA
I think there's still a lot of missing context here, and we would need you to provide it if we are to make any useful analysis. Can you provide a post of (or link to) the full code and object dump in question, or if not, a SSCCE illustrating the problem? It sounds as if a program file with just the functions start() and output_seq() may be sufficient to highlight the problem, but it isn't clear from what we've seen of the program if that is the case or not.

Re: How to compile a flat position-independent binary with G

Posted: Tue Nov 10, 2015 1:31 pm
by iansjack
OK. What you need to do now is to ask yourself what that strange "call" does. And ask yourself what is being pushed to the stack as the parameter to the "output_seq" call? And what value is that? Hmm - this is starting to get a little strange.

What you might like to do now is to get gcc to compile to an executable rather than an object file, so that any linking is done. Now have another look at that "call". Is it jumping to the same place? So where is it jumping to, and what does that function do? And what's all the other crap in the executable from what was just a few lines of source code?

This is getting complicated - far more than you might have first thought. You should also do the same exercise without the "-fPIE" option and see if anything is different.

Once you understand what is happening in both these cases you might be in a position to decide that you are going to use position-independent flat binaries, produced by gcc and doing the linking yourself, rather than ELF executables. But until then you're just shooting in the dark.

Please understand that I am not claiming to understand all that is happening in the first case; I haven't looked into it that deeply. But that's because I'm happy to work with the compiler rather than trying to wrestle with it. (Also I use 64-bit code, where position-independent code is a doddle.)

Re: How to compile a flat position-independent binary with G

Posted: Tue Nov 10, 2015 1:34 pm
by onlyonemac
I cannot provide an SSCCE because I am not fully aware of what is causing the problem. Here is absolutely everything:

beep.c

Code: Select all

#define TIME_SCALE 0x03FFFFFF

typedef unsigned char uint8_t;
typedef unsigned int uint16_t;

static void output_char(char character);
static void output_seq(char* sequence);

static void long_beep();
static void short_beep();

static void beep();
static void quiet();
static void pause();

static void out_byte(uint16_t port, uint8_t byte);
static uint8_t in_byte(uint16_t port);

void start()
{
//	char current_character;

	output_seq("sl");
//	short_beep();
//	long_beep();
}

static void output_char(char character)
{
	char uppercase_character;

	if (character >= 'a' && character <= 'z')
	{
		uppercase_character = character - ('a' - 'A');
	}
	else
	{
		uppercase_character = character;
	}

	switch (uppercase_character)
	{
		case 'A':
			output_seq("sl");
			break;
		case 'B':
			output_seq("lsss");
			break;
		case 'C':
			output_seq("lsls");
			break;
		case 'D':
			output_seq("lss");
			break;
		case 'E':
			output_seq("s");
			break;
		case 'F':
			output_seq("ssls");
			break;
		case 'G':
			output_seq("lls");
			break;
		case 'H':
			output_seq("ssss");
			break;
		case 'I':
			output_seq("ss");
			break;
		case 'J':
			output_seq("slll");
			break;
		case 'K':
			output_seq("lsl");
			break;
		case 'L':
			output_seq("slss");
			break;
		case 'M':
			output_seq("ll");
			break;
		case 'N':
			output_seq("ls");
			break;
		case 'O':
			output_seq("lll");
			break;
		case 'P':
			output_seq("slls");
			break;
		case 'Q':
			output_seq("llsl");
			break;
		case 'R':
			output_seq("sls");
			break;
		case 'S':
			output_seq("sss");
			break;
		case 'T':
			output_seq("l");
			break;
		case 'U':
			output_seq("ssl");
			break;
		case 'V':
			output_seq("sssl");
			break;
		case 'W':
			output_seq("sll");
			break;
		case 'X':
			output_seq("lssl");
			break;
		case 'y':
			output_seq("lsll");
			break;
		case 'Z':
			output_seq("llss");
			break;
		case '1':
			output_seq("sllll");
			break;
		case '2':
			output_seq("sslll");
			break;
		case '3':
			output_seq("sssll");
			break;
		case '4':
			output_seq("ssssl");
			break;
		case '5':
			output_seq("sssss");
			break;
		case '6':
			output_seq("lssss");
			break;
		case '7':
			output_seq("llsss");
			break;
		case '8':
			output_seq("lllss");
			break;
		case '9':
			output_seq("lllls");
			break;
		case '0':
			output_seq("lllll");
			break;
		case ' ':
			pause();
			pause();
			pause();
			pause();
			pause();
			break;
	}

	pause();
	pause();
}

static void output_seq(char* seq)
{
	uint8_t position;

	position = 0;
	while (seq[position] != 0)
	{
		switch (seq[position])
		{
			case 'l':
				long_beep();
				break;
			case 's':
				short_beep();
				break;
		}
		position += 1;
	}
}

static void long_beep()
{
	beep();
	pause();
	pause();
	pause();
	quiet();
	pause();
}

static void short_beep()
{
	beep();
	pause();
	quiet();
	pause();
}

static void beep()
{
	out_byte(0x0061, in_byte(0x0061) | 0x03);
}

static void quiet()
{
	out_byte(0x0061, in_byte(0x0061) & 0xFC);
}

static void pause()
{
	uint16_t loop_counter;

	loop_counter = 0;
	while(loop_counter < TIME_SCALE)
	{
		loop_counter += 1;
	}
}

static void out_byte(uint16_t port, uint8_t byte)
{
	asm volatile("outb %%al, %%dx": :"d"(port), "a"(byte));
}

static uint8_t in_byte(uint16_t port)
{
	uint8_t result;

	asm volatile("inb %%dx, %%al":"=a"(result):"d"(port));
	return result;
}
dump of beep.o, obtained with "objdump -d beep.o"

Code: Select all

beep.o:     file format elf32-i386


Disassembly of section .text:

00000000 <start>:
   0:	55                   	push   %ebp
   1:	89 e5                	mov    %esp,%ebp
   3:	53                   	push   %ebx
   4:	83 ec 04             	sub    $0x4,%esp
   7:	e8 fc ff ff ff       	call   8 <start+0x8>
   c:	81 c3 02 00 00 00    	add    $0x2,%ebx
  12:	83 ec 0c             	sub    $0xc,%esp
  15:	8d 83 00 00 00 00    	lea    0x0(%ebx),%eax
  1b:	50                   	push   %eax
  1c:	e8 b0 03 00 00       	call   3d1 <output_seq>
  21:	83 c4 10             	add    $0x10,%esp
  24:	8b 5d fc             	mov    -0x4(%ebp),%ebx
  27:	c9                   	leave  
  28:	c3                   	ret    

00000029 <output_char>:
  29:	55                   	push   %ebp
  2a:	89 e5                	mov    %esp,%ebp
  2c:	53                   	push   %ebx
  2d:	83 ec 24             	sub    $0x24,%esp
  30:	e8 fc ff ff ff       	call   31 <output_char+0x8>
  35:	81 c3 02 00 00 00    	add    $0x2,%ebx
  3b:	8b 45 08             	mov    0x8(%ebp),%eax
  3e:	88 45 e4             	mov    %al,-0x1c(%ebp)
  41:	80 7d e4 60          	cmpb   $0x60,-0x1c(%ebp)
  45:	7e 12                	jle    59 <output_char+0x30>
  47:	80 7d e4 7a          	cmpb   $0x7a,-0x1c(%ebp)
  4b:	7f 0c                	jg     59 <output_char+0x30>
  4d:	0f b6 45 e4          	movzbl -0x1c(%ebp),%eax
  51:	83 e8 20             	sub    $0x20,%eax
  54:	88 45 f7             	mov    %al,-0x9(%ebp)
  57:	eb 07                	jmp    60 <output_char+0x37>
  59:	0f b6 45 e4          	movzbl -0x1c(%ebp),%eax
  5d:	88 45 f7             	mov    %al,-0x9(%ebp)
  60:	0f be 45 f7          	movsbl -0x9(%ebp),%eax
  64:	83 e8 20             	sub    $0x20,%eax
  67:	83 f8 59             	cmp    $0x59,%eax
  6a:	0f 87 52 03 00 00    	ja     3c2 <.L5>
  70:	c1 e0 02             	shl    $0x2,%eax
  73:	8b 84 18 a8 00 00 00 	mov    0xa8(%eax,%ebx,1),%eax
  7a:	01 d8                	add    %ebx,%eax
  7c:	ff e0                	jmp    *%eax

0000007e <.L18>:
  7e:	83 ec 0c             	sub    $0xc,%esp
  81:	8d 83 00 00 00 00    	lea    0x0(%ebx),%eax
  87:	50                   	push   %eax
  88:	e8 44 03 00 00       	call   3d1 <output_seq>
  8d:	83 c4 10             	add    $0x10,%esp
  90:	e9 2d 03 00 00       	jmp    3c2 <.L5>

00000095 <.L19>:
  95:	83 ec 0c             	sub    $0xc,%esp
  98:	8d 83 03 00 00 00    	lea    0x3(%ebx),%eax
  9e:	50                   	push   %eax
  9f:	e8 2d 03 00 00       	call   3d1 <output_seq>
  a4:	83 c4 10             	add    $0x10,%esp
  a7:	e9 16 03 00 00       	jmp    3c2 <.L5>

000000ac <.L20>:
  ac:	83 ec 0c             	sub    $0xc,%esp
  af:	8d 83 08 00 00 00    	lea    0x8(%ebx),%eax
  b5:	50                   	push   %eax
  b6:	e8 16 03 00 00       	call   3d1 <output_seq>
  bb:	83 c4 10             	add    $0x10,%esp
  be:	e9 ff 02 00 00       	jmp    3c2 <.L5>

000000c3 <.L21>:
  c3:	83 ec 0c             	sub    $0xc,%esp
  c6:	8d 83 0d 00 00 00    	lea    0xd(%ebx),%eax
  cc:	50                   	push   %eax
  cd:	e8 ff 02 00 00       	call   3d1 <output_seq>
  d2:	83 c4 10             	add    $0x10,%esp
  d5:	e9 e8 02 00 00       	jmp    3c2 <.L5>

000000da <.L22>:
  da:	83 ec 0c             	sub    $0xc,%esp
  dd:	8d 83 11 00 00 00    	lea    0x11(%ebx),%eax
  e3:	50                   	push   %eax
  e4:	e8 e8 02 00 00       	call   3d1 <output_seq>
  e9:	83 c4 10             	add    $0x10,%esp
  ec:	e9 d1 02 00 00       	jmp    3c2 <.L5>

000000f1 <.L23>:
  f1:	83 ec 0c             	sub    $0xc,%esp
  f4:	8d 83 13 00 00 00    	lea    0x13(%ebx),%eax
  fa:	50                   	push   %eax
  fb:	e8 d1 02 00 00       	call   3d1 <output_seq>
 100:	83 c4 10             	add    $0x10,%esp
 103:	e9 ba 02 00 00       	jmp    3c2 <.L5>

00000108 <.L24>:
 108:	83 ec 0c             	sub    $0xc,%esp
 10b:	8d 83 18 00 00 00    	lea    0x18(%ebx),%eax
 111:	50                   	push   %eax
 112:	e8 ba 02 00 00       	call   3d1 <output_seq>
 117:	83 c4 10             	add    $0x10,%esp
 11a:	e9 a3 02 00 00       	jmp    3c2 <.L5>

0000011f <.L25>:
 11f:	83 ec 0c             	sub    $0xc,%esp
 122:	8d 83 1c 00 00 00    	lea    0x1c(%ebx),%eax
 128:	50                   	push   %eax
 129:	e8 a3 02 00 00       	call   3d1 <output_seq>
 12e:	83 c4 10             	add    $0x10,%esp
 131:	e9 8c 02 00 00       	jmp    3c2 <.L5>

00000136 <.L26>:
 136:	83 ec 0c             	sub    $0xc,%esp
 139:	8d 83 21 00 00 00    	lea    0x21(%ebx),%eax
 13f:	50                   	push   %eax
 140:	e8 8c 02 00 00       	call   3d1 <output_seq>
 145:	83 c4 10             	add    $0x10,%esp
 148:	e9 75 02 00 00       	jmp    3c2 <.L5>

0000014d <.L27>:
 14d:	83 ec 0c             	sub    $0xc,%esp
 150:	8d 83 24 00 00 00    	lea    0x24(%ebx),%eax
 156:	50                   	push   %eax
 157:	e8 75 02 00 00       	call   3d1 <output_seq>
 15c:	83 c4 10             	add    $0x10,%esp
 15f:	e9 5e 02 00 00       	jmp    3c2 <.L5>

00000164 <.L28>:
 164:	83 ec 0c             	sub    $0xc,%esp
 167:	8d 83 29 00 00 00    	lea    0x29(%ebx),%eax
 16d:	50                   	push   %eax
 16e:	e8 5e 02 00 00       	call   3d1 <output_seq>
 173:	83 c4 10             	add    $0x10,%esp
 176:	e9 47 02 00 00       	jmp    3c2 <.L5>

0000017b <.L29>:
 17b:	83 ec 0c             	sub    $0xc,%esp
 17e:	8d 83 2d 00 00 00    	lea    0x2d(%ebx),%eax
 184:	50                   	push   %eax
 185:	e8 47 02 00 00       	call   3d1 <output_seq>
 18a:	83 c4 10             	add    $0x10,%esp
 18d:	e9 30 02 00 00       	jmp    3c2 <.L5>

00000192 <.L30>:
 192:	83 ec 0c             	sub    $0xc,%esp
 195:	8d 83 32 00 00 00    	lea    0x32(%ebx),%eax
 19b:	50                   	push   %eax
 19c:	e8 30 02 00 00       	call   3d1 <output_seq>
 1a1:	83 c4 10             	add    $0x10,%esp
 1a4:	e9 19 02 00 00       	jmp    3c2 <.L5>

000001a9 <.L31>:
 1a9:	83 ec 0c             	sub    $0xc,%esp
 1ac:	8d 83 35 00 00 00    	lea    0x35(%ebx),%eax
 1b2:	50                   	push   %eax
 1b3:	e8 19 02 00 00       	call   3d1 <output_seq>
 1b8:	83 c4 10             	add    $0x10,%esp
 1bb:	e9 02 02 00 00       	jmp    3c2 <.L5>

000001c0 <.L32>:
 1c0:	83 ec 0c             	sub    $0xc,%esp
 1c3:	8d 83 38 00 00 00    	lea    0x38(%ebx),%eax
 1c9:	50                   	push   %eax
 1ca:	e8 02 02 00 00       	call   3d1 <output_seq>
 1cf:	83 c4 10             	add    $0x10,%esp
 1d2:	e9 eb 01 00 00       	jmp    3c2 <.L5>

000001d7 <.L33>:
 1d7:	83 ec 0c             	sub    $0xc,%esp
 1da:	8d 83 3c 00 00 00    	lea    0x3c(%ebx),%eax
 1e0:	50                   	push   %eax
 1e1:	e8 eb 01 00 00       	call   3d1 <output_seq>
 1e6:	83 c4 10             	add    $0x10,%esp
 1e9:	e9 d4 01 00 00       	jmp    3c2 <.L5>

000001ee <.L34>:
 1ee:	83 ec 0c             	sub    $0xc,%esp
 1f1:	8d 83 41 00 00 00    	lea    0x41(%ebx),%eax
 1f7:	50                   	push   %eax
 1f8:	e8 d4 01 00 00       	call   3d1 <output_seq>
 1fd:	83 c4 10             	add    $0x10,%esp
 200:	e9 bd 01 00 00       	jmp    3c2 <.L5>

00000205 <.L35>:
 205:	83 ec 0c             	sub    $0xc,%esp
 208:	8d 83 46 00 00 00    	lea    0x46(%ebx),%eax
 20e:	50                   	push   %eax
 20f:	e8 bd 01 00 00       	call   3d1 <output_seq>
 214:	83 c4 10             	add    $0x10,%esp
 217:	e9 a6 01 00 00       	jmp    3c2 <.L5>

0000021c <.L36>:
 21c:	83 ec 0c             	sub    $0xc,%esp
 21f:	8d 83 4a 00 00 00    	lea    0x4a(%ebx),%eax
 225:	50                   	push   %eax
 226:	e8 a6 01 00 00       	call   3d1 <output_seq>
 22b:	83 c4 10             	add    $0x10,%esp
 22e:	e9 8f 01 00 00       	jmp    3c2 <.L5>

00000233 <.L37>:
 233:	83 ec 0c             	sub    $0xc,%esp
 236:	8d 83 4e 00 00 00    	lea    0x4e(%ebx),%eax
 23c:	50                   	push   %eax
 23d:	e8 8f 01 00 00       	call   3d1 <output_seq>
 242:	83 c4 10             	add    $0x10,%esp
 245:	e9 78 01 00 00       	jmp    3c2 <.L5>

0000024a <.L38>:
 24a:	83 ec 0c             	sub    $0xc,%esp
 24d:	8d 83 50 00 00 00    	lea    0x50(%ebx),%eax
 253:	50                   	push   %eax
 254:	e8 78 01 00 00       	call   3d1 <output_seq>
 259:	83 c4 10             	add    $0x10,%esp
 25c:	e9 61 01 00 00       	jmp    3c2 <.L5>

00000261 <.L39>:
 261:	83 ec 0c             	sub    $0xc,%esp
 264:	8d 83 54 00 00 00    	lea    0x54(%ebx),%eax
 26a:	50                   	push   %eax
 26b:	e8 61 01 00 00       	call   3d1 <output_seq>
 270:	83 c4 10             	add    $0x10,%esp
 273:	e9 4a 01 00 00       	jmp    3c2 <.L5>

00000278 <.L40>:
 278:	83 ec 0c             	sub    $0xc,%esp
 27b:	8d 83 59 00 00 00    	lea    0x59(%ebx),%eax
 281:	50                   	push   %eax
 282:	e8 4a 01 00 00       	call   3d1 <output_seq>
 287:	83 c4 10             	add    $0x10,%esp
 28a:	e9 33 01 00 00       	jmp    3c2 <.L5>

0000028f <.L41>:
 28f:	83 ec 0c             	sub    $0xc,%esp
 292:	8d 83 5d 00 00 00    	lea    0x5d(%ebx),%eax
 298:	50                   	push   %eax
 299:	e8 33 01 00 00       	call   3d1 <output_seq>
 29e:	83 c4 10             	add    $0x10,%esp
 2a1:	e9 1c 01 00 00       	jmp    3c2 <.L5>

000002a6 <.L43>:
 2a6:	83 ec 0c             	sub    $0xc,%esp
 2a9:	8d 83 62 00 00 00    	lea    0x62(%ebx),%eax
 2af:	50                   	push   %eax
 2b0:	e8 1c 01 00 00       	call   3d1 <output_seq>
 2b5:	83 c4 10             	add    $0x10,%esp
 2b8:	e9 05 01 00 00       	jmp    3c2 <.L5>

000002bd <.L42>:
 2bd:	83 ec 0c             	sub    $0xc,%esp
 2c0:	8d 83 67 00 00 00    	lea    0x67(%ebx),%eax
 2c6:	50                   	push   %eax
 2c7:	e8 05 01 00 00       	call   3d1 <output_seq>
 2cc:	83 c4 10             	add    $0x10,%esp
 2cf:	e9 ee 00 00 00       	jmp    3c2 <.L5>

000002d4 <.L9>:
 2d4:	83 ec 0c             	sub    $0xc,%esp
 2d7:	8d 83 6c 00 00 00    	lea    0x6c(%ebx),%eax
 2dd:	50                   	push   %eax
 2de:	e8 ee 00 00 00       	call   3d1 <output_seq>
 2e3:	83 c4 10             	add    $0x10,%esp
 2e6:	e9 d7 00 00 00       	jmp    3c2 <.L5>

000002eb <.L10>:
 2eb:	83 ec 0c             	sub    $0xc,%esp
 2ee:	8d 83 72 00 00 00    	lea    0x72(%ebx),%eax
 2f4:	50                   	push   %eax
 2f5:	e8 d7 00 00 00       	call   3d1 <output_seq>
 2fa:	83 c4 10             	add    $0x10,%esp
 2fd:	e9 c0 00 00 00       	jmp    3c2 <.L5>

00000302 <.L11>:
 302:	83 ec 0c             	sub    $0xc,%esp
 305:	8d 83 78 00 00 00    	lea    0x78(%ebx),%eax
 30b:	50                   	push   %eax
 30c:	e8 c0 00 00 00       	call   3d1 <output_seq>
 311:	83 c4 10             	add    $0x10,%esp
 314:	e9 a9 00 00 00       	jmp    3c2 <.L5>

00000319 <.L12>:
 319:	83 ec 0c             	sub    $0xc,%esp
 31c:	8d 83 7e 00 00 00    	lea    0x7e(%ebx),%eax
 322:	50                   	push   %eax
 323:	e8 a9 00 00 00       	call   3d1 <output_seq>
 328:	83 c4 10             	add    $0x10,%esp
 32b:	e9 92 00 00 00       	jmp    3c2 <.L5>

00000330 <.L13>:
 330:	83 ec 0c             	sub    $0xc,%esp
 333:	8d 83 84 00 00 00    	lea    0x84(%ebx),%eax
 339:	50                   	push   %eax
 33a:	e8 92 00 00 00       	call   3d1 <output_seq>
 33f:	83 c4 10             	add    $0x10,%esp
 342:	eb 7e                	jmp    3c2 <.L5>

00000344 <.L14>:
 344:	83 ec 0c             	sub    $0xc,%esp
 347:	8d 83 8a 00 00 00    	lea    0x8a(%ebx),%eax
 34d:	50                   	push   %eax
 34e:	e8 7e 00 00 00       	call   3d1 <output_seq>
 353:	83 c4 10             	add    $0x10,%esp
 356:	eb 6a                	jmp    3c2 <.L5>

00000358 <.L15>:
 358:	83 ec 0c             	sub    $0xc,%esp
 35b:	8d 83 90 00 00 00    	lea    0x90(%ebx),%eax
 361:	50                   	push   %eax
 362:	e8 6a 00 00 00       	call   3d1 <output_seq>
 367:	83 c4 10             	add    $0x10,%esp
 36a:	eb 56                	jmp    3c2 <.L5>

0000036c <.L16>:
 36c:	83 ec 0c             	sub    $0xc,%esp
 36f:	8d 83 96 00 00 00    	lea    0x96(%ebx),%eax
 375:	50                   	push   %eax
 376:	e8 56 00 00 00       	call   3d1 <output_seq>
 37b:	83 c4 10             	add    $0x10,%esp
 37e:	eb 42                	jmp    3c2 <.L5>

00000380 <.L17>:
 380:	83 ec 0c             	sub    $0xc,%esp
 383:	8d 83 9c 00 00 00    	lea    0x9c(%ebx),%eax
 389:	50                   	push   %eax
 38a:	e8 42 00 00 00       	call   3d1 <output_seq>
 38f:	83 c4 10             	add    $0x10,%esp
 392:	eb 2e                	jmp    3c2 <.L5>

00000394 <.L8>:
 394:	83 ec 0c             	sub    $0xc,%esp
 397:	8d 83 a2 00 00 00    	lea    0xa2(%ebx),%eax
 39d:	50                   	push   %eax
 39e:	e8 2e 00 00 00       	call   3d1 <output_seq>
 3a3:	83 c4 10             	add    $0x10,%esp
 3a6:	eb 1a                	jmp    3c2 <.L5>

000003a8 <.L6>:
 3a8:	e8 04 01 00 00       	call   4b1 <pause>
 3ad:	e8 ff 00 00 00       	call   4b1 <pause>
 3b2:	e8 fa 00 00 00       	call   4b1 <pause>
 3b7:	e8 f5 00 00 00       	call   4b1 <pause>
 3bc:	e8 f0 00 00 00       	call   4b1 <pause>
 3c1:	90                   	nop

000003c2 <.L5>:
 3c2:	e8 ea 00 00 00       	call   4b1 <pause>
 3c7:	e8 e5 00 00 00       	call   4b1 <pause>
 3cc:	8b 5d fc             	mov    -0x4(%ebp),%ebx
 3cf:	c9                   	leave  
 3d0:	c3                   	ret    

000003d1 <output_seq>:
 3d1:	55                   	push   %ebp
 3d2:	89 e5                	mov    %esp,%ebp
 3d4:	83 ec 18             	sub    $0x18,%esp
 3d7:	c6 45 f7 00          	movb   $0x0,-0x9(%ebp)
 3db:	eb 2c                	jmp    409 <output_seq+0x38>
 3dd:	0f b6 55 f7          	movzbl -0x9(%ebp),%edx
 3e1:	8b 45 08             	mov    0x8(%ebp),%eax
 3e4:	01 d0                	add    %edx,%eax
 3e6:	0f b6 00             	movzbl (%eax),%eax
 3e9:	0f be c0             	movsbl %al,%eax
 3ec:	83 f8 6c             	cmp    $0x6c,%eax
 3ef:	74 07                	je     3f8 <output_seq+0x27>
 3f1:	83 f8 73             	cmp    $0x73,%eax
 3f4:	74 09                	je     3ff <output_seq+0x2e>
 3f6:	eb 0d                	jmp    405 <output_seq+0x34>
 3f8:	e8 1e 00 00 00       	call   41b <long_beep>
 3fd:	eb 06                	jmp    405 <output_seq+0x34>
 3ff:	e8 3d 00 00 00       	call   441 <short_beep>
 404:	90                   	nop
 405:	80 45 f7 01          	addb   $0x1,-0x9(%ebp)
 409:	0f b6 55 f7          	movzbl -0x9(%ebp),%edx
 40d:	8b 45 08             	mov    0x8(%ebp),%eax
 410:	01 d0                	add    %edx,%eax
 412:	0f b6 00             	movzbl (%eax),%eax
 415:	84 c0                	test   %al,%al
 417:	75 c4                	jne    3dd <output_seq+0xc>
 419:	c9                   	leave  
 41a:	c3                   	ret    

0000041b <long_beep>:
 41b:	55                   	push   %ebp
 41c:	89 e5                	mov    %esp,%ebp
 41e:	83 ec 08             	sub    $0x8,%esp
 421:	e8 37 00 00 00       	call   45d <beep>
 426:	e8 86 00 00 00       	call   4b1 <pause>
 42b:	e8 81 00 00 00       	call   4b1 <pause>
 430:	e8 7c 00 00 00       	call   4b1 <pause>
 435:	e8 4c 00 00 00       	call   486 <quiet>
 43a:	e8 72 00 00 00       	call   4b1 <pause>
 43f:	c9                   	leave  
 440:	c3                   	ret    

00000441 <short_beep>:
 441:	55                   	push   %ebp
 442:	89 e5                	mov    %esp,%ebp
 444:	83 ec 08             	sub    $0x8,%esp
 447:	e8 11 00 00 00       	call   45d <beep>
 44c:	e8 60 00 00 00       	call   4b1 <pause>
 451:	e8 30 00 00 00       	call   486 <quiet>
 456:	e8 56 00 00 00       	call   4b1 <pause>
 45b:	c9                   	leave  
 45c:	c3                   	ret    

0000045d <beep>:
 45d:	55                   	push   %ebp
 45e:	89 e5                	mov    %esp,%ebp
 460:	83 ec 08             	sub    $0x8,%esp
 463:	83 ec 0c             	sub    $0xc,%esp
 466:	6a 61                	push   $0x61
 468:	e8 78 00 00 00       	call   4e5 <in_byte>
 46d:	83 c4 10             	add    $0x10,%esp
 470:	83 c8 03             	or     $0x3,%eax
 473:	0f b6 c0             	movzbl %al,%eax
 476:	83 ec 08             	sub    $0x8,%esp
 479:	50                   	push   %eax
 47a:	6a 61                	push   $0x61
 47c:	e8 4e 00 00 00       	call   4cf <out_byte>
 481:	83 c4 10             	add    $0x10,%esp
 484:	c9                   	leave  
 485:	c3                   	ret    

00000486 <quiet>:
 486:	55                   	push   %ebp
 487:	89 e5                	mov    %esp,%ebp
 489:	83 ec 08             	sub    $0x8,%esp
 48c:	83 ec 0c             	sub    $0xc,%esp
 48f:	6a 61                	push   $0x61
 491:	e8 4f 00 00 00       	call   4e5 <in_byte>
 496:	83 c4 10             	add    $0x10,%esp
 499:	0f b6 c0             	movzbl %al,%eax
 49c:	25 fc 00 00 00       	and    $0xfc,%eax
 4a1:	83 ec 08             	sub    $0x8,%esp
 4a4:	50                   	push   %eax
 4a5:	6a 61                	push   $0x61
 4a7:	e8 23 00 00 00       	call   4cf <out_byte>
 4ac:	83 c4 10             	add    $0x10,%esp
 4af:	c9                   	leave  
 4b0:	c3                   	ret    

000004b1 <pause>:
 4b1:	55                   	push   %ebp
 4b2:	89 e5                	mov    %esp,%ebp
 4b4:	83 ec 10             	sub    $0x10,%esp
 4b7:	c7 45 fc 00 00 00 00 	movl   $0x0,-0x4(%ebp)
 4be:	eb 04                	jmp    4c4 <pause+0x13>
 4c0:	83 45 fc 01          	addl   $0x1,-0x4(%ebp)
 4c4:	81 7d fc fe ff ff 03 	cmpl   $0x3fffffe,-0x4(%ebp)
 4cb:	76 f3                	jbe    4c0 <pause+0xf>
 4cd:	c9                   	leave  
 4ce:	c3                   	ret    

000004cf <out_byte>:
 4cf:	55                   	push   %ebp
 4d0:	89 e5                	mov    %esp,%ebp
 4d2:	83 ec 04             	sub    $0x4,%esp
 4d5:	8b 45 0c             	mov    0xc(%ebp),%eax
 4d8:	88 45 fc             	mov    %al,-0x4(%ebp)
 4db:	8b 55 08             	mov    0x8(%ebp),%edx
 4de:	0f b6 45 fc          	movzbl -0x4(%ebp),%eax
 4e2:	ee                   	out    %al,(%dx)
 4e3:	c9                   	leave  
 4e4:	c3                   	ret    

000004e5 <in_byte>:
 4e5:	55                   	push   %ebp
 4e6:	89 e5                	mov    %esp,%ebp
 4e8:	83 ec 10             	sub    $0x10,%esp
 4eb:	8b 45 08             	mov    0x8(%ebp),%eax
 4ee:	89 c2                	mov    %eax,%edx
 4f0:	ec                   	in     (%dx),%al
 4f1:	88 45 ff             	mov    %al,-0x1(%ebp)
 4f4:	0f b6 45 ff          	movzbl -0x1(%ebp),%eax
 4f8:	c9                   	leave  
 4f9:	c3                   	ret    

Disassembly of section .text.__x86.get_pc_thunk.bx:

00000000 <__x86.get_pc_thunk.bx>:
   0:	8b 1c 24             	mov    (%esp),%ebx
   3:	c3                   	ret    
makefile

Code: Select all

beep.bin: beep.c
	./make-flat-binary beep
	chmod a-x beep.bin
make-flat-binary

Code: Select all

#!/bin/sh

gcc -fPIE -ffreestanding -fno-builtin -nostdlib -nostdinc -m32 -Wl,-Bstatic -Wall -c $1.c -o $1.o
#objcopy --only-section .text --output-target binary $1.o $1.bin
ld -o $1.bin -T linkscript.lds $1.o
linkscript.lds

Code: Select all

OUTPUT_FORMAT("binary")
OUTPUT_ARCH(i386)
ENTRY(start)
phys = 0x00000000;
SECTIONS
{
  .text phys : AT(phys) {
    code = .;
    *(.text)
    *(.rodata)
    . = ALIGN(4096);
  }
  .data : AT(phys + (data - code))
  {
    data = .;
    *(.data)
    . = ALIGN(4096);
  }
  .bss : AT(phys + (bss - code))
  {
    bss = .;
    *(.bss)
    . = ALIGN(4096);
  }
  end = .;
}
And finally, the purpose of the code module is ultimately to take a string and output it as morse code for debugging purposes.

Re: How to compile a flat position-independent binary with G

Posted: Tue Nov 10, 2015 1:44 pm
by BASICFreak
Every char array you have points to .got

The only way I have successfully got a PIE/PIC (binary) to work was without any constants - all data must be dynamically initialized or you must use an output format that allows the .got section

You could always try adding the .got section to the ld script - IIRC it failed too...

BTW try the -shared flag instead of -fPIE as it does not produce the .got section (At least on my ELF loader)



Happy hacking,

B!

Re: How to compile a flat position-independent binary with G

Posted: Tue Nov 10, 2015 1:48 pm
by iansjack
The "__x86.get_pc_thunk.bx" function is important to you.

But, as I have said before, I think you are going to find this a whole lot more work that using relocatable ELF files. (And, no, I'm not trying to persuade you to do that; just giving my estimate of the relative complexity of the two methods.)

Re: How to compile a flat position-independent binary with G

Posted: Tue Nov 10, 2015 1:59 pm
by onlyonemac
iansjack wrote:OK. What you need to do now is to ask yourself what that strange "call" does. And ask yourself what is being pushed to the stack as the parameter to the "output_seq" call? And what value is that? Hmm - this is starting to get a little strange.
Yeah it's strange alright but without knowing what the call does I can't figure out why we're pushing an uninitialised register onto the stack. And I can't figure out what the call does because I think the call is only "filled in" by the linker, which is refusing to run.
iansjack wrote:What you might like to do now is to get gcc to compile to an executable rather than an object file, so that any linking is done. Now have another look at that "call". Is it jumping to the same place? So where is it jumping to, and what does that function do? And what's all the other crap in the executable from what was just a few lines of source code?
I just tried doing this now and it's jumping to the function "__x86.get_pc_thunk.bx" at the end of the object file. (I had previously guessed this when I saw that function there in the object dump and googled it and found that it has something to do with position-independent code.)
iansjack wrote:This is getting complicated - far more than you might have first thought. You should also do the same exercise without the "-fPIE" option and see if anything is different.
Nothing changes with regards to the weird function call.

So, how does this help me? I've found out that the weird call and the instructions before it:
  • push the (uninitialised) ebx onto the stack
  • decrease the stack pointer by 4 so that it is now the same as before the push
  • move the location pointed to by the stack pointer into ebx (effectively a pop ebx without altering the stack pointer)
How does this help me? I still see no references to any global table thingy.

Re: How to compile a flat position-independent binary with G

Posted: Tue Nov 10, 2015 2:02 pm
by onlyonemac
iansjack wrote:But, as I have said before, I think you are going to find this a whole lot more work that using relocatable ELF files. (And, no, I'm not trying to persuade you to do that; just giving my estimate of the relative complexity of the two methods.)
Fair enough, you're not trying to persuade me to use ELF files, but then perhaps you should stop mentioning ELF files. Imagine trying to execute a non-position-independent function that's located at an arbitrary address in a structure of linked-list objects. With ELF you'll have to copy it somewhere else to execute it - and that somewhere else will be at whatever load address the ELF file demands and now we have to do the whole paging thing instead of having the entire operating system (except for the kernel) constructed out of one large hierarchical linked list in a flat memory model. And speaking of kernels, it's not like I can make my kernel an ELF file.