How does the `--defsym` linker flag work to pass values to source code?
In an LJ post, the --defsym
flag was used for passing the build date into the source code:
#include <stdio.h>
extern char __BUILD_DATE;
void main(void)
printf("Build date: %un", (unsigned long) &__BUILD_DATE);
by linking with the following flags:
gcc example.c -Xlinker --defsym -Xlinker __BUILD_DATE=$(date +%Y%m%d)
According to the ld manual,
--defsym symbol=expression
Create a global symbol in the output file, containing the absolute address given by expression.
I am trying to understand the following:
- How is the 9-character string for the build date (
YYYYmmdd
+) stored in memory?
- If
--defsym
creates a symbol containing an address, why__BUILD_DATE
is defined as a char and not as a pointer or as an integral type? - Why
__BUILD_DATE
is defined aschar
and notunsigned long
if it is eventually casted tounsigned long
?
c++ c gcc casting linker
add a comment |
In an LJ post, the --defsym
flag was used for passing the build date into the source code:
#include <stdio.h>
extern char __BUILD_DATE;
void main(void)
printf("Build date: %un", (unsigned long) &__BUILD_DATE);
by linking with the following flags:
gcc example.c -Xlinker --defsym -Xlinker __BUILD_DATE=$(date +%Y%m%d)
According to the ld manual,
--defsym symbol=expression
Create a global symbol in the output file, containing the absolute address given by expression.
I am trying to understand the following:
- How is the 9-character string for the build date (
YYYYmmdd
+) stored in memory?
- If
--defsym
creates a symbol containing an address, why__BUILD_DATE
is defined as a char and not as a pointer or as an integral type? - Why
__BUILD_DATE
is defined aschar
and notunsigned long
if it is eventually casted tounsigned long
?
c++ c gcc casting linker
That looks like 3 questions to me. Not one. Maybe you want to post 3 individual questions..?
– Jesper Juhl
Nov 12 '18 at 22:10
@JesperJuhl I think it's 3 small parts of one questions about the usage of--defsym
. It makes no sense to me to split the question.
– Sparkler
Nov 12 '18 at 22:14
"Why __BUILD_DATE is defined as char and not unsigned long if it is eventually casted to unsigned long?" Is definitely a standalone question IMHO. As is "If --defsym creates a symbol containing an address, why __BUILD_DATE is defined as a char and not as a pointer or as an integral type?". But, that may just be me.
– Jesper Juhl
Nov 12 '18 at 22:17
add a comment |
In an LJ post, the --defsym
flag was used for passing the build date into the source code:
#include <stdio.h>
extern char __BUILD_DATE;
void main(void)
printf("Build date: %un", (unsigned long) &__BUILD_DATE);
by linking with the following flags:
gcc example.c -Xlinker --defsym -Xlinker __BUILD_DATE=$(date +%Y%m%d)
According to the ld manual,
--defsym symbol=expression
Create a global symbol in the output file, containing the absolute address given by expression.
I am trying to understand the following:
- How is the 9-character string for the build date (
YYYYmmdd
+) stored in memory?
- If
--defsym
creates a symbol containing an address, why__BUILD_DATE
is defined as a char and not as a pointer or as an integral type? - Why
__BUILD_DATE
is defined aschar
and notunsigned long
if it is eventually casted tounsigned long
?
c++ c gcc casting linker
In an LJ post, the --defsym
flag was used for passing the build date into the source code:
#include <stdio.h>
extern char __BUILD_DATE;
void main(void)
printf("Build date: %un", (unsigned long) &__BUILD_DATE);
by linking with the following flags:
gcc example.c -Xlinker --defsym -Xlinker __BUILD_DATE=$(date +%Y%m%d)
According to the ld manual,
--defsym symbol=expression
Create a global symbol in the output file, containing the absolute address given by expression.
I am trying to understand the following:
- How is the 9-character string for the build date (
YYYYmmdd
+) stored in memory?
- If
--defsym
creates a symbol containing an address, why__BUILD_DATE
is defined as a char and not as a pointer or as an integral type? - Why
__BUILD_DATE
is defined aschar
and notunsigned long
if it is eventually casted tounsigned long
?
c++ c gcc casting linker
c++ c gcc casting linker
edited Nov 12 '18 at 22:15
asked Nov 12 '18 at 21:59
Sparkler
760824
760824
That looks like 3 questions to me. Not one. Maybe you want to post 3 individual questions..?
– Jesper Juhl
Nov 12 '18 at 22:10
@JesperJuhl I think it's 3 small parts of one questions about the usage of--defsym
. It makes no sense to me to split the question.
– Sparkler
Nov 12 '18 at 22:14
"Why __BUILD_DATE is defined as char and not unsigned long if it is eventually casted to unsigned long?" Is definitely a standalone question IMHO. As is "If --defsym creates a symbol containing an address, why __BUILD_DATE is defined as a char and not as a pointer or as an integral type?". But, that may just be me.
– Jesper Juhl
Nov 12 '18 at 22:17
add a comment |
That looks like 3 questions to me. Not one. Maybe you want to post 3 individual questions..?
– Jesper Juhl
Nov 12 '18 at 22:10
@JesperJuhl I think it's 3 small parts of one questions about the usage of--defsym
. It makes no sense to me to split the question.
– Sparkler
Nov 12 '18 at 22:14
"Why __BUILD_DATE is defined as char and not unsigned long if it is eventually casted to unsigned long?" Is definitely a standalone question IMHO. As is "If --defsym creates a symbol containing an address, why __BUILD_DATE is defined as a char and not as a pointer or as an integral type?". But, that may just be me.
– Jesper Juhl
Nov 12 '18 at 22:17
That looks like 3 questions to me. Not one. Maybe you want to post 3 individual questions..?
– Jesper Juhl
Nov 12 '18 at 22:10
That looks like 3 questions to me. Not one. Maybe you want to post 3 individual questions..?
– Jesper Juhl
Nov 12 '18 at 22:10
@JesperJuhl I think it's 3 small parts of one questions about the usage of
--defsym
. It makes no sense to me to split the question.– Sparkler
Nov 12 '18 at 22:14
@JesperJuhl I think it's 3 small parts of one questions about the usage of
--defsym
. It makes no sense to me to split the question.– Sparkler
Nov 12 '18 at 22:14
"Why __BUILD_DATE is defined as char and not unsigned long if it is eventually casted to unsigned long?" Is definitely a standalone question IMHO. As is "If --defsym creates a symbol containing an address, why __BUILD_DATE is defined as a char and not as a pointer or as an integral type?". But, that may just be me.
– Jesper Juhl
Nov 12 '18 at 22:17
"Why __BUILD_DATE is defined as char and not unsigned long if it is eventually casted to unsigned long?" Is definitely a standalone question IMHO. As is "If --defsym creates a symbol containing an address, why __BUILD_DATE is defined as a char and not as a pointer or as an integral type?". But, that may just be me.
– Jesper Juhl
Nov 12 '18 at 22:17
add a comment |
1 Answer
1
active
oldest
votes
Linkers see globals as addresses (pointers to the "actual" global rather than the actual global -- even if the actual global doesn't exist at that address). -Xlinker --defsym -Xlinker __BUILD_DATE=$(date +%Y%m%d)
sets the address of __BUILD_DATE
not the value. When the __BUILD_DATE
linker entity has an address but not a value, you can get the address by declaring the entity as anything and then taking the address of that.
In:
#include <stdio.h>
//extern long __BUILD_DATE[128];
//extern int __BUILD_DATE;
extern char __BUILD_DATE;
int main(void)
printf("Build date: %lun", (unsigned long)&__BUILD_DATE);
Any of the three declarations should work. Just don't try to use the value of that (pseudo) global. That would be like dereferencing an invalid pointer.
That should answer 2 and 3. To answer 1, -Xlinker --defsym -Xlinker __BUILD_DATE=$(date +%Y%m%d)
stores the number returned (stdout) by $(date %Y%m%d)
as the address of __BUILD_DATE
. It doesn't store a string.
so anything passed using--defsym
can only be as large assize_t
/ptrdiff_t
?
– Sparkler
Nov 12 '18 at 22:59
@Sparkler There doesn't need to be much of a correlation between the linker's limits and the limits of C types, but practically you very likely won't be able to store addresses larger than your SIZE_MAX.
– PSkocik
Nov 12 '18 at 23:02
1
Interestingly, the above's only working for me with clang. I can't quite get it to work if I use gcc for linking (with whatever-fuse-ld
option or without it). The debugger always shows the stored timestamp if I dop (unsigned long)&__BUILD_DATE
but the program's printing the stored value offset by0xffffaaaaaaaac000
but only if my system's address layout randomization's off. (Otherwise it's random). I don't have an explanation for this.
– PSkocik
Nov 12 '18 at 23:07
add a comment |
Your Answer
StackExchange.ifUsing("editor", function ()
StackExchange.using("externalEditor", function ()
StackExchange.using("snippets", function ()
StackExchange.snippets.init();
);
);
, "code-snippets");
StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "1"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);
else
createEditor();
);
function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader:
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
,
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);
);
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53270723%2fhow-does-the-defsym-linker-flag-work-to-pass-values-to-source-code%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
Linkers see globals as addresses (pointers to the "actual" global rather than the actual global -- even if the actual global doesn't exist at that address). -Xlinker --defsym -Xlinker __BUILD_DATE=$(date +%Y%m%d)
sets the address of __BUILD_DATE
not the value. When the __BUILD_DATE
linker entity has an address but not a value, you can get the address by declaring the entity as anything and then taking the address of that.
In:
#include <stdio.h>
//extern long __BUILD_DATE[128];
//extern int __BUILD_DATE;
extern char __BUILD_DATE;
int main(void)
printf("Build date: %lun", (unsigned long)&__BUILD_DATE);
Any of the three declarations should work. Just don't try to use the value of that (pseudo) global. That would be like dereferencing an invalid pointer.
That should answer 2 and 3. To answer 1, -Xlinker --defsym -Xlinker __BUILD_DATE=$(date +%Y%m%d)
stores the number returned (stdout) by $(date %Y%m%d)
as the address of __BUILD_DATE
. It doesn't store a string.
so anything passed using--defsym
can only be as large assize_t
/ptrdiff_t
?
– Sparkler
Nov 12 '18 at 22:59
@Sparkler There doesn't need to be much of a correlation between the linker's limits and the limits of C types, but practically you very likely won't be able to store addresses larger than your SIZE_MAX.
– PSkocik
Nov 12 '18 at 23:02
1
Interestingly, the above's only working for me with clang. I can't quite get it to work if I use gcc for linking (with whatever-fuse-ld
option or without it). The debugger always shows the stored timestamp if I dop (unsigned long)&__BUILD_DATE
but the program's printing the stored value offset by0xffffaaaaaaaac000
but only if my system's address layout randomization's off. (Otherwise it's random). I don't have an explanation for this.
– PSkocik
Nov 12 '18 at 23:07
add a comment |
Linkers see globals as addresses (pointers to the "actual" global rather than the actual global -- even if the actual global doesn't exist at that address). -Xlinker --defsym -Xlinker __BUILD_DATE=$(date +%Y%m%d)
sets the address of __BUILD_DATE
not the value. When the __BUILD_DATE
linker entity has an address but not a value, you can get the address by declaring the entity as anything and then taking the address of that.
In:
#include <stdio.h>
//extern long __BUILD_DATE[128];
//extern int __BUILD_DATE;
extern char __BUILD_DATE;
int main(void)
printf("Build date: %lun", (unsigned long)&__BUILD_DATE);
Any of the three declarations should work. Just don't try to use the value of that (pseudo) global. That would be like dereferencing an invalid pointer.
That should answer 2 and 3. To answer 1, -Xlinker --defsym -Xlinker __BUILD_DATE=$(date +%Y%m%d)
stores the number returned (stdout) by $(date %Y%m%d)
as the address of __BUILD_DATE
. It doesn't store a string.
so anything passed using--defsym
can only be as large assize_t
/ptrdiff_t
?
– Sparkler
Nov 12 '18 at 22:59
@Sparkler There doesn't need to be much of a correlation between the linker's limits and the limits of C types, but practically you very likely won't be able to store addresses larger than your SIZE_MAX.
– PSkocik
Nov 12 '18 at 23:02
1
Interestingly, the above's only working for me with clang. I can't quite get it to work if I use gcc for linking (with whatever-fuse-ld
option or without it). The debugger always shows the stored timestamp if I dop (unsigned long)&__BUILD_DATE
but the program's printing the stored value offset by0xffffaaaaaaaac000
but only if my system's address layout randomization's off. (Otherwise it's random). I don't have an explanation for this.
– PSkocik
Nov 12 '18 at 23:07
add a comment |
Linkers see globals as addresses (pointers to the "actual" global rather than the actual global -- even if the actual global doesn't exist at that address). -Xlinker --defsym -Xlinker __BUILD_DATE=$(date +%Y%m%d)
sets the address of __BUILD_DATE
not the value. When the __BUILD_DATE
linker entity has an address but not a value, you can get the address by declaring the entity as anything and then taking the address of that.
In:
#include <stdio.h>
//extern long __BUILD_DATE[128];
//extern int __BUILD_DATE;
extern char __BUILD_DATE;
int main(void)
printf("Build date: %lun", (unsigned long)&__BUILD_DATE);
Any of the three declarations should work. Just don't try to use the value of that (pseudo) global. That would be like dereferencing an invalid pointer.
That should answer 2 and 3. To answer 1, -Xlinker --defsym -Xlinker __BUILD_DATE=$(date +%Y%m%d)
stores the number returned (stdout) by $(date %Y%m%d)
as the address of __BUILD_DATE
. It doesn't store a string.
Linkers see globals as addresses (pointers to the "actual" global rather than the actual global -- even if the actual global doesn't exist at that address). -Xlinker --defsym -Xlinker __BUILD_DATE=$(date +%Y%m%d)
sets the address of __BUILD_DATE
not the value. When the __BUILD_DATE
linker entity has an address but not a value, you can get the address by declaring the entity as anything and then taking the address of that.
In:
#include <stdio.h>
//extern long __BUILD_DATE[128];
//extern int __BUILD_DATE;
extern char __BUILD_DATE;
int main(void)
printf("Build date: %lun", (unsigned long)&__BUILD_DATE);
Any of the three declarations should work. Just don't try to use the value of that (pseudo) global. That would be like dereferencing an invalid pointer.
That should answer 2 and 3. To answer 1, -Xlinker --defsym -Xlinker __BUILD_DATE=$(date +%Y%m%d)
stores the number returned (stdout) by $(date %Y%m%d)
as the address of __BUILD_DATE
. It doesn't store a string.
edited Nov 12 '18 at 23:09
answered Nov 12 '18 at 22:29
PSkocik
32.2k54770
32.2k54770
so anything passed using--defsym
can only be as large assize_t
/ptrdiff_t
?
– Sparkler
Nov 12 '18 at 22:59
@Sparkler There doesn't need to be much of a correlation between the linker's limits and the limits of C types, but practically you very likely won't be able to store addresses larger than your SIZE_MAX.
– PSkocik
Nov 12 '18 at 23:02
1
Interestingly, the above's only working for me with clang. I can't quite get it to work if I use gcc for linking (with whatever-fuse-ld
option or without it). The debugger always shows the stored timestamp if I dop (unsigned long)&__BUILD_DATE
but the program's printing the stored value offset by0xffffaaaaaaaac000
but only if my system's address layout randomization's off. (Otherwise it's random). I don't have an explanation for this.
– PSkocik
Nov 12 '18 at 23:07
add a comment |
so anything passed using--defsym
can only be as large assize_t
/ptrdiff_t
?
– Sparkler
Nov 12 '18 at 22:59
@Sparkler There doesn't need to be much of a correlation between the linker's limits and the limits of C types, but practically you very likely won't be able to store addresses larger than your SIZE_MAX.
– PSkocik
Nov 12 '18 at 23:02
1
Interestingly, the above's only working for me with clang. I can't quite get it to work if I use gcc for linking (with whatever-fuse-ld
option or without it). The debugger always shows the stored timestamp if I dop (unsigned long)&__BUILD_DATE
but the program's printing the stored value offset by0xffffaaaaaaaac000
but only if my system's address layout randomization's off. (Otherwise it's random). I don't have an explanation for this.
– PSkocik
Nov 12 '18 at 23:07
so anything passed using
--defsym
can only be as large as size_t
/ptrdiff_t
?– Sparkler
Nov 12 '18 at 22:59
so anything passed using
--defsym
can only be as large as size_t
/ptrdiff_t
?– Sparkler
Nov 12 '18 at 22:59
@Sparkler There doesn't need to be much of a correlation between the linker's limits and the limits of C types, but practically you very likely won't be able to store addresses larger than your SIZE_MAX.
– PSkocik
Nov 12 '18 at 23:02
@Sparkler There doesn't need to be much of a correlation between the linker's limits and the limits of C types, but practically you very likely won't be able to store addresses larger than your SIZE_MAX.
– PSkocik
Nov 12 '18 at 23:02
1
1
Interestingly, the above's only working for me with clang. I can't quite get it to work if I use gcc for linking (with whatever
-fuse-ld
option or without it). The debugger always shows the stored timestamp if I do p (unsigned long)&__BUILD_DATE
but the program's printing the stored value offset by 0xffffaaaaaaaac000
but only if my system's address layout randomization's off. (Otherwise it's random). I don't have an explanation for this.– PSkocik
Nov 12 '18 at 23:07
Interestingly, the above's only working for me with clang. I can't quite get it to work if I use gcc for linking (with whatever
-fuse-ld
option or without it). The debugger always shows the stored timestamp if I do p (unsigned long)&__BUILD_DATE
but the program's printing the stored value offset by 0xffffaaaaaaaac000
but only if my system's address layout randomization's off. (Otherwise it's random). I don't have an explanation for this.– PSkocik
Nov 12 '18 at 23:07
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Some of your past answers have not been well-received, and you're in danger of being blocked from answering.
Please pay close attention to the following guidance:
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53270723%2fhow-does-the-defsym-linker-flag-work-to-pass-values-to-source-code%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
That looks like 3 questions to me. Not one. Maybe you want to post 3 individual questions..?
– Jesper Juhl
Nov 12 '18 at 22:10
@JesperJuhl I think it's 3 small parts of one questions about the usage of
--defsym
. It makes no sense to me to split the question.– Sparkler
Nov 12 '18 at 22:14
"Why __BUILD_DATE is defined as char and not unsigned long if it is eventually casted to unsigned long?" Is definitely a standalone question IMHO. As is "If --defsym creates a symbol containing an address, why __BUILD_DATE is defined as a char and not as a pointer or as an integral type?". But, that may just be me.
– Jesper Juhl
Nov 12 '18 at 22:17