Accessing section attributes from assembly (or C)

Christopher Bahns
Wed Jul 5 04:08:00 GMT 2000

I'm sorry, it would appear that the simple example I showed you *does* work, which
is good. However, my initial error happened when I tried to use the linker-script
symbols in an expression (I oversimplified my problem in the last message).

Try this for the linker script excerpt:
  tables : {
        tables1_start = .;
        tables1_end = .;

        tables2_start = .;
        tables2_end = .;
  } > rom

  tables1_size = tables1_end - tables1_start;
  tables2_size = tables2_end - tables2_start;

Now let's say we want to put the sum of the two sizes in our assembly code:
"   .extern tables1_size\n"
"   .extern tables2_size\n"
"            DC.B  0x01\n"                  /* UBYTE table format version */
"            DC.B  0x00\n"                  /* UBYTE unused_a for alignment */
"            DC.L  (tables1_size + tables2_size)\n"

With this the assembler gives me:
"Error: undefined symbol __data_end in operation"
"Error: undefined symbol __data_start in operation"

I know what I can do: define yet another variable in the linker script:
        "tables_size = tables2_end - tables1_start"
or something like this. I really don't like this because there are quite a few
references throughout my C/assembly code referring to section starting addresses
and sizes. It seems a bit kludgy to have to make up a new variable in the linker
script for every calculated value that is required in the source code. I'd like my
linker scripts just to provide the necessary information for the link, and not
have too many cross-dependencies between my source code and linker scripts. The
linker script should not have to change each time I want to get information in a
slightly different way from source code. It seems that MRI can do this, but GNU
(as far as I know) cannot.

The following code works with MRI:
#pragma asm
   XDEF   _DATA_Table
            DC.B  $01                  /* UBYTE table format version */
            DC.B  $00                  /* UBYTE unused_a for alignment */
            DC.L  .SIZEOF.(tables1)+.SIZEOF.(tables2)
#pragma endasm

In this case I don't have to define any additional symbols in the linker script.
It is very easy to put section information directly into the source code, and
combine them in an expression. Does anyone know a way to do something similar with
GNU? If you can think of an easier to accomplish what I'm trying to do, please let
me know.

Sorry for the functional example in the last message.

Christopher Bahns wrote:

> How can I access information about a section from within my C or
> assembly code? Specifically, I need to know the starting address and
> size (or ending address) of a section. Now, I already know how to do
> this as a C-language variable, but I think I need access to these values
> as literals. Hold on a sec and I'll show why...
> Here is an excerpt from my linker script:
> __________________________________________________________________
>   .my_tables : {
>         __tables_start = .;
>         *(.my_tables)
>         __tables_end = .;
>         __tables_size = __tables_end - __tables_start;
>   } > rom
> __________________________________________________________________
> And here is some assembly code (inside a C file):
> __________________________________________________________________
> __asm__(
> "   .extern __tables_size\n"
> "DATA_Table:\n"
> "            DC.B  0x01\n"                  /* UBYTE table format
> version */
> "            DC.B  0x00\n"                  /* UBYTE unused_a for
> alignment */
> "            DC.L  __tables_size\n"
> )
> __________________________________________________________________
> Note that the linker would have to put the final (literal) value of
> "__tables_size" directly at this location at link time. I can't really
> use a variable to refer to "__tables_size" and copy the value to this
> location at run time (at least not easily). The above code generates an
> error in the assembler: "Error: undefined symbol __tables_size in
> operation".
> It is possible to do this with MRI (I am converting from MRI to GNU), so
> I really hope GNU has an easy way to do this as well. I've looked
> through some of the documentation but not thoroughly. If you can point
> me to the right part of the documentation please do. I *really* don't
> want to use MRI-compatibility mode. I've already gotten most of it
> converted to GNU and would like to move totally from the old syntax. If
> GNU simply cannot do some of the nice things that MRI can do, then I'll
> be sorely disappointed.
> Here is the corresponding MRI-compatible assembly code:
> __________________________________________________________________
> #pragma asm
>    XDEF   _DATA_Table
> _DATA_Table:
>             DC.B  $01                  /* UBYTE table format version */
>             DC.B  $00                  /* UBYTE unused_a for alignment
> */
>             DC.L  .SIZEOF.(.my_tables)
> #pragma endasm
> __________________________________________________________________
> As you can see with MRI it is easy. I can have the linker just stick the
> size of the ".my_tables" section directly at the desired location, using
> the ".SIZEOF." directive. MRI also has a ".STARTOF." directive for
> obtaining the start address of a section.
> Can anyone help? (Thanks to those that helped me with other stuff...
> almost there now.)
> Chris
>   ------------------------------------------------------------------------
> ------
> Want more information?  See the CrossGCC FAQ,
> Want to unsubscribe? Send a note to

More information about the crossgcc mailing list